Skip to content

fix(voip): remove sensitive data from production logs#7207

Merged
diegolmello merged 3 commits into
feat.voip-lib-newfrom
pr/voip-secure-logs-6918
Apr 22, 2026
Merged

fix(voip): remove sensitive data from production logs#7207
diegolmello merged 3 commits into
feat.voip-lib-newfrom
pr/voip-secure-logs-6918

Conversation

@diegolmello

@diegolmello diegolmello commented Apr 22, 2026

Copy link
Copy Markdown
Member

Summary

Defense-in-depth for VoIP secure logging. Complements the existing babel transform that strips console.log in production by removing sensitive data at the source level in both JS and Android native code.

Changes

JS/TS — console.log removal (source-level):

  • MediaSessionInstance.ts: Removed all console.log calls and the // TODO: Show error message? comment
  • MediaSessionStore.ts: Removed console.log('[VoIP] Mobile device ID:', mobileDeviceId)

Android Kotlin — BuildConfig.DEBUG gating:

  • DDPClient.kt: All sensitive Log.d calls (wsUrl, connection, login, subscribe, method calls) gated behind if (BuildConfig.DEBUG)
  • VoipNotification.kt: ~30 sensitive logs (DDP listener, callId, host, WebSocket messages) gated
  • VoipModule.kt: addListener/removeListeners event name logs gated
  • VoipCallService.kt: Service lifecycle logs gated
  • IncomingCallActivity.kt: Activity creation/call accepted/declined logs gated

Android Kotlin — response body removal:

  • MediaCallsAnswerRequest.kt: Removed HTTP response body logging (lines 125, 127) that could expose session tokens/crypto material

Sensitive data removed from production logs

  • callId (call identifiers)
  • Host URLs and wsUrl (WebSocket URLs)
  • Device IDs (ANDROID_ID)
  • WebSocket message content (DDP messages)
  • HTTP response bodies (answer request responses)

Preserved for production support

  • All Log.e (error logs needed for debugging)
  • All console.error in JS
  • Operational logs (notification lifecycle, TelecomManager failures, security exceptions, unknown action warnings)

Merge Order

Part of the VoIP secure logs cleanup. No dependencies.

Test plan

  • TZ=UTC yarn test -- --testPathPattern='app/lib/services/voip/MediaSession' passes
  • yarn lint passes
  • Android unit tests pass (./gradlew :app:testDebugUnitTest --tests "chat.rocket.reactnative.voip.*")

Summary by CodeRabbit

  • Chores
    • Reduced verbose debug logging across VoIP call and notification flows; debug messages now only appear in debug builds or were removed to cut noise. No functional changes to call behavior, UI, or call lifecycle.

Defense-in-depth alongside babel console removal:
- Remove all console.log from MediaSessionInstance.ts and MediaSessionStore.ts
- Gate sensitive Android Log.d/Log.w calls behind BuildConfig.DEBUG (DDPClient,
  VoipNotification, VoipModule, VoipCallService, IncomingCallActivity)
- Remove HTTP response body logging from MediaCallsAnswerRequest.kt

Sensitive data removed from production logs: callId, host URLs, wsUrl,
device IDs, WebSocket messages, HTTP response bodies.

Preserves operational logs (Log.e for errors) for production support.
@coderabbitai

coderabbitai Bot commented Apr 22, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

Reduced debug logging across VoIP code: removed or gated many console/Log.d statements in TypeScript and Android files, renamed an unused callback parameter to _oldState. No control flow, public APIs, or functional behavior were changed.

Changes

Cohort / File(s) Summary
VoIP service (TS)
app/lib/services/voip/MediaSessionInstance.ts, app/lib/services/voip/MediaSessionStore.ts
Removed multiple console.log debug statements related to DDP media signals, call lifecycle, and device IDs. Renamed unused oldState parameter to _oldState and left handler empty.
Android: DDP & call lifecycle logging
android/app/src/main/java/chat/rocket/reactnative/voip/DDPClient.kt, android/app/src/main/java/chat/rocket/reactnative/voip/IncomingCallActivity.kt
Wrapped debug Log.d calls with if (BuildConfig.DEBUG) to restrict debug output to debug builds; added BuildConfig imports. Error logs unchanged.
Android: HTTP response logging
android/app/src/main/java/chat/rocket/reactnative/voip/MediaCallsAnswerRequest.kt
Removed response-status logging; retained success determination (code in 200..299) and result posting.
Android: VoIP module & service logging
android/app/src/main/java/chat/rocket/reactnative/voip/VoipCallService.kt, android/app/src/main/java/chat/rocket/reactnative/voip/VoipModule.kt, android/app/src/main/java/chat/rocket/reactnative/voip/VoipNotification.kt
Gated many debug/info Log.d/Log.w statements behind BuildConfig.DEBUG; added imports. Functional behavior, notifications, and non-debug logs left intact.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested labels

type: chore

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix(voip): remove sensitive data from production logs' accurately summarizes the main objective of the changeset—removing sensitive information from logs across both JS/TS and Android code.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

Warning

Review ran into problems

🔥 Problems

Errors were encountered while retrieving linked issues.

Errors (1)
  • LOGS-6918: Request failed with status code 401

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Defense-in-depth alongside babel console removal:
- Remove all console.log from MediaSessionInstance.ts and MediaSessionStore.ts
- Gate sensitive Android Log.d/Log.w calls behind BuildConfig.DEBUG (DDPClient,
  VoipNotification, VoipModule, VoipCallService, IncomingCallActivity)
- Remove HTTP response body logging from MediaCallsAnswerRequest.kt

Sensitive data removed from production logs: callId, host URLs, wsUrl,
device IDs, WebSocket messages, HTTP response bodies.

Preserves operational logs (Log.e for errors) for production support.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
app/lib/services/voip/MediaSessionInstance.ts (1)

116-118: Consider removing the empty event handler if not required.

The stateChange event handler is now empty after removing the sensitive logging. While the underscore prefix for the unused parameter follows convention, if this handler serves no purpose, consider removing the entire call.emitter.on('stateChange', ...) registration to reduce unnecessary overhead.

If the handler must remain registered (e.g., to prevent warnings or errors from the event system), the current implementation is correct.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/lib/services/voip/MediaSessionInstance.ts` around lines 116 - 118, The
empty stateChange handler on call.emitter in MediaSessionInstance adds
unnecessary overhead; remove the entire call.emitter.on('stateChange', _oldState
=> { ... }) registration unless the event must be subscribed to (e.g., to avoid
runtime warnings). If you must keep it, leave it as-is; otherwise delete the
call.emitter.on('stateChange', ...) line to stop registering a no-op listener.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@app/lib/services/voip/MediaSessionInstance.ts`:
- Around line 116-118: The empty stateChange handler on call.emitter in
MediaSessionInstance adds unnecessary overhead; remove the entire
call.emitter.on('stateChange', _oldState => { ... }) registration unless the
event must be subscribed to (e.g., to avoid runtime warnings). If you must keep
it, leave it as-is; otherwise delete the call.emitter.on('stateChange', ...)
line to stop registering a no-op listener.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 7a6c4317-dec1-4b26-9352-6ae96cd8fa51

📥 Commits

Reviewing files that changed from the base of the PR and between 7301db6 and ed36940.

📒 Files selected for processing (2)
  • app/lib/services/voip/MediaSessionInstance.ts
  • app/lib/services/voip/MediaSessionStore.ts
💤 Files with no reviewable changes (1)
  • app/lib/services/voip/MediaSessionStore.ts
📜 Review details
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{js,jsx,ts,tsx,json}

📄 CodeRabbit inference engine (CLAUDE.md)

Configure Prettier with tabs, single quotes, 130 character width, no trailing commas, arrow parens avoid, and bracket same line

Files:

  • app/lib/services/voip/MediaSessionInstance.ts
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use ESLint with @rocket.chat/eslint-config base configuration including React, React Native, TypeScript, and Jest plugins

Files:

  • app/lib/services/voip/MediaSessionInstance.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use TypeScript with strict mode enabled and configure baseUrl to app/ for import resolution

**/*.{ts,tsx}: Use TypeScript for type safety; add explicit type annotations to function parameters and return types
Prefer interfaces over type aliases for defining object shapes in TypeScript
Use enums for sets of related constants rather than magic strings or numbers

Files:

  • app/lib/services/voip/MediaSessionInstance.ts
app/lib/services/voip/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Implement VoIP with WebRTC peer-to-peer audio calls in app/lib/services/voip/ using Zustand stores instead of Redux, with native CallKit (iOS) and Telecom (Android) integration; keep VoIP and VideoConf separate

Files:

  • app/lib/services/voip/MediaSessionInstance.ts
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,ts,jsx,tsx}: Use descriptive names for functions, variables, and classes that clearly convey their purpose
Write comments that explain the 'why' behind code decisions, not the 'what'
Keep functions small and focused on a single responsibility
Use const by default, let when reassignment is needed, and avoid var
Prefer async/await over .then() chains for handling asynchronous operations
Use explicit error handling with try/catch blocks for async operations
Avoid deeply nested code; refactor complex logic into helper functions

Files:

  • app/lib/services/voip/MediaSessionInstance.ts
🧠 Learnings (3)
📓 Common learnings
Learnt from: CR
Repo: RocketChat/Rocket.Chat.ReactNative PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-07T17:49:17.538Z
Learning: Applies to app/lib/services/voip/**/*.{ts,tsx} : Implement VoIP with WebRTC peer-to-peer audio calls in app/lib/services/voip/ using Zustand stores instead of Redux, with native CallKit (iOS) and Telecom (Android) integration; keep VoIP and VideoConf separate
Learnt from: CR
Repo: RocketChat/Rocket.Chat.ReactNative PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-07T17:49:17.538Z
Learning: Applies to @(app/sagas/videoConf.ts|app/lib/methods/videoConf.ts) : Manage video conferencing via Redux actions/reducers/sagas in app/sagas/videoConf.ts and app/lib/methods/videoConf.ts using server-managed Jitsi integration; do not conflate with VoIP
📚 Learning: 2026-04-07T17:49:17.538Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat.ReactNative PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-07T17:49:17.538Z
Learning: Applies to app/lib/services/voip/**/*.{ts,tsx} : Implement VoIP with WebRTC peer-to-peer audio calls in app/lib/services/voip/ using Zustand stores instead of Redux, with native CallKit (iOS) and Telecom (Android) integration; keep VoIP and VideoConf separate

Applied to files:

  • app/lib/services/voip/MediaSessionInstance.ts
📚 Learning: 2026-04-07T17:49:17.538Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat.ReactNative PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-07T17:49:17.538Z
Learning: Applies to @(app/sagas/videoConf.ts|app/lib/methods/videoConf.ts) : Manage video conferencing via Redux actions/reducers/sagas in app/sagas/videoConf.ts and app/lib/methods/videoConf.ts using server-managed Jitsi integration; do not conflate with VoIP

Applied to files:

  • app/lib/services/voip/MediaSessionInstance.ts
🔇 Additional comments (1)
app/lib/services/voip/MediaSessionInstance.ts (1)

1-257: Security improvements successfully implemented.

The removal of sensitive console.log statements while preserving console.error and console.warn calls aligns perfectly with the PR's defense-in-depth approach for VoIP secure logging. The changes protect sensitive data (callId, state transitions, DDP message content) from production logs while maintaining essential error reporting for production support.

@diegolmello diegolmello had a problem deploying to official_android_build April 22, 2026 17:46 — with GitHub Actions Error
@diegolmello diegolmello had a problem deploying to experimental_android_build April 22, 2026 17:46 — with GitHub Actions Error
@diegolmello diegolmello requested a deployment to experimental_ios_build April 22, 2026 17:46 — with GitHub Actions Waiting

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
android/app/src/main/java/chat/rocket/reactnative/voip/MediaCallsAnswerRequest.kt (1)

95-97: ⚠️ Potential issue | 🟠 Major

Remove remaining sensitive values from production logs.

Line 96 still logs host, and Line 116 still logs callId; both are listed as sensitive by the PR objective. Also consider avoiding e.message here because networking exceptions can include endpoint details.

🔒 Proposed log sanitization
-            Log.w(TAG, "Missing credentials for $host — cannot send media-call answer")
+            Log.w(TAG, "Missing credentials — cannot send media-call answer")
...
-                Log.e(TAG, "MediaCallsAnswerRequest failed for callId=$callId: ${e.message}")
+                Log.e(TAG, "MediaCallsAnswerRequest failed: ${e.javaClass.simpleName}")

Also applies to: 115-117

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@android/app/src/main/java/chat/rocket/reactnative/voip/MediaCallsAnswerRequest.kt`
around lines 95 - 97, In MediaCallsAnswerRequest, remove sensitive values from
logs: stop logging the host and callId variables in Log.w/Log.e calls (replace
with generic messages like "Missing credentials" or "Failed to send media-call
answer") and avoid printing exception messages that may contain endpoint details
(do not use e.message); instead log a non-sensitive error note or use
e.toString()/log exception type without payload if needed. Update the checks and
catch blocks referencing host and callId to use the class/method names
(MediaCallsAnswerRequest / onResult callback) in the messages so logs remain
informative but contain no host/callId or raw exception message.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In
`@android/app/src/main/java/chat/rocket/reactnative/voip/MediaCallsAnswerRequest.kt`:
- Around line 95-97: In MediaCallsAnswerRequest, remove sensitive values from
logs: stop logging the host and callId variables in Log.w/Log.e calls (replace
with generic messages like "Missing credentials" or "Failed to send media-call
answer") and avoid printing exception messages that may contain endpoint details
(do not use e.message); instead log a non-sensitive error note or use
e.toString()/log exception type without payload if needed. Update the checks and
catch blocks referencing host and callId to use the class/method names
(MediaCallsAnswerRequest / onResult callback) in the messages so logs remain
informative but contain no host/callId or raw exception message.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 92490959-89d1-4826-943d-d67749fc34bf

📥 Commits

Reviewing files that changed from the base of the PR and between ed36940 and f546e8d.

📒 Files selected for processing (6)
  • android/app/src/main/java/chat/rocket/reactnative/voip/DDPClient.kt
  • android/app/src/main/java/chat/rocket/reactnative/voip/IncomingCallActivity.kt
  • android/app/src/main/java/chat/rocket/reactnative/voip/MediaCallsAnswerRequest.kt
  • android/app/src/main/java/chat/rocket/reactnative/voip/VoipCallService.kt
  • android/app/src/main/java/chat/rocket/reactnative/voip/VoipModule.kt
  • android/app/src/main/java/chat/rocket/reactnative/voip/VoipNotification.kt
✅ Files skipped from review due to trivial changes (1)
  • android/app/src/main/java/chat/rocket/reactnative/voip/IncomingCallActivity.kt
📜 Review details
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: CR
Repo: RocketChat/Rocket.Chat.ReactNative PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-07T17:49:17.538Z
Learning: Applies to app/lib/services/voip/**/*.{ts,tsx} : Implement VoIP with WebRTC peer-to-peer audio calls in app/lib/services/voip/ using Zustand stores instead of Redux, with native CallKit (iOS) and Telecom (Android) integration; keep VoIP and VideoConf separate
📚 Learning: 2026-04-07T17:49:17.538Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat.ReactNative PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-07T17:49:17.538Z
Learning: Applies to app/lib/services/voip/**/*.{ts,tsx} : Implement VoIP with WebRTC peer-to-peer audio calls in app/lib/services/voip/ using Zustand stores instead of Redux, with native CallKit (iOS) and Telecom (Android) integration; keep VoIP and VideoConf separate

Applied to files:

  • android/app/src/main/java/chat/rocket/reactnative/voip/VoipCallService.kt
  • android/app/src/main/java/chat/rocket/reactnative/voip/VoipNotification.kt
📚 Learning: 2026-03-31T11:59:31.061Z
Learnt from: Rohit3523
Repo: RocketChat/Rocket.Chat.ReactNative PR: 6875
File: android/build.gradle:3-8
Timestamp: 2026-03-31T11:59:31.061Z
Learning: In the RocketChat/Rocket.Chat.ReactNative repository, the React Native upgrade helper (https://react-native-community.github.io/upgrade-helper/?from=0.79.4&to=0.81.5) recommends kotlinVersion = "2.1.20", compileSdkVersion = 36, targetSdkVersion = 36, and buildToolsVersion = "36.0.0" in android/build.gradle for the RN 0.79.4 → 0.81.5 upgrade. These are the sanctioned values for this upgrade path and should not be flagged as compatibility concerns.

Applied to files:

  • android/app/src/main/java/chat/rocket/reactnative/voip/VoipModule.kt
  • android/app/src/main/java/chat/rocket/reactnative/voip/DDPClient.kt
📚 Learning: 2026-02-05T13:55:06.688Z
Learnt from: Rohit3523
Repo: RocketChat/Rocket.Chat.ReactNative PR: 6930
File: package.json:101-101
Timestamp: 2026-02-05T13:55:06.688Z
Learning: The RocketChat/Rocket.Chat.ReactNative repository uses a fork of react-native-image-crop-picker (RocketChat/react-native-image-crop-picker) with custom Android edge-to-edge fixes, not the upstream ivpusic/react-native-image-crop-picker package. Dependencies should reference commit pins from the RocketChat fork.

Applied to files:

  • android/app/src/main/java/chat/rocket/reactnative/voip/VoipModule.kt
🔇 Additional comments (5)
android/app/src/main/java/chat/rocket/reactnative/voip/MediaCallsAnswerRequest.kt (1)

120-124: LGTM: response body logging is removed.

The response handler now derives success from the status code only and avoids logging the HTTP response body.

android/app/src/main/java/chat/rocket/reactnative/voip/VoipCallService.kt (1)

74-109: LGTM — callId is properly suppressed in release builds.

Both callId-carrying Log.d sites are gated behind BuildConfig.DEBUG, and the remaining ungated logs ("Service already running…", lifecycle onCreate/onDestroy, Log.w unknown action) carry no sensitive data. Consistent with the PR's defense-in-depth goal.

android/app/src/main/java/chat/rocket/reactnative/voip/VoipModule.kt (1)

107-161: LGTM.

callId in the expired-event log is now suppressed in release builds, matching the PR's sensitive-data goal. The remaining ungated Log.d calls (clearInitialEventsInternal, registerVoipToken, stopNativeDDPClient, removeListeners) carry no PII, which is consistent.

android/app/src/main/java/chat/rocket/reactnative/voip/DDPClient.kt (1)

54-181: LGTM — all sensitive DDP debug logs gated.

wsUrl (host), subscription names, and handshake milestones are now debug-only; Log.e paths (including onFailure's t.message, Login failed, Failed to subscribe, Method … failed, Connect timeout) are preserved for production triage. Good balance between privacy and supportability.

android/app/src/main/java/chat/rocket/reactnative/voip/VoipNotification.kt (1)

99-955: LGTM — comprehensive gating across timeout, accept/decline, DDP, and notification paths.

Sensitive values (callId, caller, host, extras keys, raw DDP messages via Log.d(TAG, "DDP received message: $message")) are all now debug-only, while Log.e error paths and the operational Log.w for unsupported payload types / full-screen intent fallback remain in production as intended.

One minor note for awareness (no change requested): registerCallWithTelecomManager's Log.e at line 752 includes callId/caller in the error string. This is preserved per PR scope ("All Log.e error logs remain unchanged") and is useful for triaging rejected payloads, but if caller can be a phone number / PII it's worth a follow-up to redact in a later pass.

@diegolmello diegolmello had a problem deploying to official_android_build April 22, 2026 17:58 — with GitHub Actions Failure
@diegolmello diegolmello had a problem deploying to experimental_android_build April 22, 2026 17:58 — with GitHub Actions Failure
@diegolmello diegolmello had a problem deploying to experimental_ios_build April 22, 2026 17:58 — with GitHub Actions Failure
@diegolmello diegolmello merged commit 10ae82a into feat.voip-lib-new Apr 22, 2026
5 of 10 checks passed
@diegolmello diegolmello deleted the pr/voip-secure-logs-6918 branch April 22, 2026 19:38
diegolmello added a commit that referenced this pull request Apr 22, 2026
…/Decline (#7215)

* merge feat.voip-lib

* feat(voip): enhance call handling with UUID mapping and event listeners

* Base call UI

* feat(voip): integrate Zustand for call state management and enhance CallView UI

* feat(voip): add simulateCall function for mock call handling in UI development

* refactor(CallView): update button handlers and improve UI responsiveness

* Add pause-shape-unfilled icon

* Base CallHeader

* toggleFocus

* collapse buttons

* Header components

* Hide header when no call

* Timer

* Add use memo

* Add voice call item on sidebar

* cleanup

* Temp use @rocket.chat/media-signaling from .tgz

* cleanup

* Check module and permissions to enable voip

* Refactor stop method to use optional chaining for media signal listeners

* voip push first test

* Add VoIP call handling with pending call management

- Implemented VoIP push notification handling in index.js, including storing call info for later processing.
- Added CallKeep event handlers for answering and ending calls from a cold start.
- Introduced a new CallIdUUID module to convert call IDs to deterministic UUIDs for compatibility with CallKit.
- Created a pending call store to manage incoming calls when the app is not fully initialized.
- Updated deep linking actions to include VoIP call handling.
- Enhanced MediaSessionInstance to process pending calls and manage call states effectively.

* Remove pending store and create getInitialEvents on app/index

* Attempt to make iOS calls work from cold state

* lint and format

* Patch callkeep ios

* Temp send iOS voip push token on gcm

* Temp fix require cycle

* chore: format code and fix lint issues [skip ci]

* CallIDUUID module on android and voip push

* Add setCallUUID on useCallStore to persist calls accepted on native Android

* remove callkeep from notification

* Android Incoming Call UI POC

* Refactor VoIP handling: Migrate VoIP-related classes to a new package structure, removing deprecated modules and consolidating functionality. Update imports in MainApplication and NotificationIntentHandler to reflect changes. This cleanup enhances code organization and prepares for future VoIP feature enhancements.

* Remove VoipForegroundService

* cleanup and use caller instead of callerName

* Cleanup and make iOS build again

* Refactor VoIP handling: Remove unused event emissions for call answered and declined, switch from SharedPreferences to in-memory storage for pending VoIP call data, and update method signatures for better clarity. This cleanup enhances performance and prepares for future VoIP feature improvements.

* Refactor VoIP handling: Introduce a new VoipPayload class to encapsulate call data, streamline notification processing, and enhance method signatures across the VoIP module. This update improves code clarity and prepares for future feature enhancements.

* Migrate react-native-voip-push-notifications to VoipModule

* Refactor VoIP module: Update package structure by moving VoipTurboPackage to the main package and removing the obsolete NativeVoipSpec class. Adjust imports in MainApplication and VoipModule to reflect these changes, enhancing code organization and maintainability.

* Unify emitters

* Move CallKeep listeners from MediaSessionInstance to getInitialEvents

* Clear callkeep on endcall

* Unify getInitialEvents logic

* getInitialEvents -> MediaCallEvents

* chore: format code and fix lint issues [skip ci]

* feat(Android): Add full screen incoming call (#6977)

* feat: Update call UI (#6990)

* feat: Handle audio routing, e.g., Bluetooth headset vs. internal speaker switching (#6992)

* fix: empty space when not on call (#6993)

* feat: Dialpad (#7000)

* action: organized translations

* feat: start call (#7024)

* chore: format code and fix lint issues

* feat: Pre flight (#7038)

* action: organized translations

* feat: Receive voip push notifications from backend (#7045)

* feat: Refactor media session handling and improve disconnect logic (#7065)

* feat: Control incoming call from native (#7066)

* feat: Voice message blocks (#7057)

* feat: native accept success event (#7068)

* feat(voip): call waiting, busy detection, and videoconf blocking (#7077)

* action: organized translations

* feat(voip): tap-to-hide call controls with animations (#7078)

* feat(voip): navigate to call DM from message button and header (#7082)

* feat(voip): tablet and landscape layout (#7110)

* chore: develop into feat.voip-lib-new (RN 81 + Expo 54 + reanimated 4 + true-sheet + iOS 26) (#7114)

* chore: format code and fix lint issues

* feat(voip): android landscape layout for IncomingCallActivity (#7116)

* Update agents files

* feat(voip): Support a11y (#7106)

* Fix content cutting on iOS on some edge cases

* pods

* Ignore .worktrees on jest

* chore: Merge develop into feat.voip-lib-new (#7129)

* fix(voip): show CallKit UI when call is active in background (#7128)

* chore: Update media-signaling to 0.2.0 (#7153)

* feat(voip): migrate iOS accept/reject from DDP to REST (#7124)

* Fix icons

* feat(voip): migrate Android accept/reject from DDP to REST (#7127)

* test(voip): integration tests for CallView pipeline (#7161)

* feat(voip): display video conf provider as subtitle (#7160)

* fix(voip): CallView button grid and correct landscape/dialpad layouts (#7164)

* fix(voip): prevent stale MMKV cache on Android first-install accept

MMKVKeyManager.initialize ran in MainApplication.onCreate before the JS
engine started and opened the default MMKV file via the Tencent 1.2 JAR
when it was still empty. Tencent caches instances per-ID in a singleton
registry, so that empty-state view was held for the rest of the process.
JS later wrote credentials through react-native-mmkv (MMKV Core 2.0),
which has its own separate registry. When a VoIP push arrived,
Ejson.getMMKV() got the cached empty Tencent instance and reported
"No userId found in MMKV for server". Closing and reopening the app
cleared the cache, which is why only the very first call after install
failed.

Drop the open/verify block — the encryption key is already cached from
SecureKeystore, so no MMKV handle is needed here. The first Tencent
instance is now created inside Ejson.getMMKV() after JS has written,
so it scans the file fresh.

* fix(voip): prevent duplicate ringtone on Android incoming call (#7158)

* fix(voip): set explicit snaps for NewMediaCall bottom sheet (#7165)

* Update app/lib/services/voip/MediaSessionStore.ts

Co-authored-by: Pierre Lehnen <55164754+pierre-lehnen-rc@users.noreply.github.com>

* fix: make startVoipFork reactive to permissions-changed (#7151)

* fix(android): remove MediaProjectionService from merged manifest (#7190)

* fix(voip): Phone account creation (#7170)

* feat: add Enable Mobile Ringing toggle in user preferences (#7155)

* fix(voip): ship blockers for PushKit, licensing, outbound calls, push tokens (#7167)

* fix(android): Play Store mic discoverability, safer FCM logs, avatar auth via headers (#7171)

* fix(ios): serialize VoipService bridge statics (#7169)

* fix(voip): Android DDP thread safety and VoipPayload bundle parity (#7168)

* chore(voip): dead-code and hygiene sweep (#7174)

* refactor(voip): decouple navigateToCallRoom from Redux and backfill REST/connect tests (#7176)

* test(voip): tighten ringing endCall assertion and add VideoConf VoIP-lock saga coverage (#7177)

* fix(ios): harden VoIP DDP WebSocket client on receive failures and TLS (#7173)

* refactor(voip): MediaCallEvents Redux adapters and resetVoipState (#7178)

* refactor(voip): decouple peer autocomplete from Redux; simplify NewMediaCall (#7175)

* fix(ios): add NS_SWIFT_NAME to Challenge.runChallenge for Swift 6.2 compatibility

Swift 6.2 (Xcode 26.x / macos-26 runner) auto-renames the Objective-C
method runChallenge:didReceiveChallenge:completionHandler: to
run(_:didReceive:completionHandler:) when imported into Swift.

Add NS_SWIFT_NAME to explicitly pin the Swift import name, preventing
the compiler from applying its heuristics. This keeps the existing
Swift call site in DDPClient.swift working without changes.

* fix(ios): cancel old URLSession/webSocketTask before reconnecting in DDPClient.connect (#7197)

* fix(ios): add NSLock to nativeAcceptHandledCallIds and 10s REST timeout to handleNativeAccept (#7198)

* feat(android): create VoipCallService with FOREGROUND_SERVICE_MICROPHONE (#7199)

* fix(android): start VoipCallService on accept, stop on hangup/timeout, install end-call listener (#7200)

* fix(voip): enable DM nav for users with SIP extension (#7203)

* fix(android): handle null VoiceConnection in answerIncomingCall, notify JS (#7201)

* fix(voip): resolve closure capture ordering in handleNativeAccept (#7209)

* fix(android): integrate VoIP modules with SSL-pinned OkHttpClient (#7208)

* fix(push): gate id and voipToken behind server version checks, fix VideoConf caller extra (#7210)

* fix(voip): remove sensitive data from production logs (#7207)

* fix(android): remove isRunning guard + add double-tap guard on Accept/Decline

- VoipCallService: remove if (!isRunning) guard, call startForeground unconditionally
  (idempotent on Android, fixes Android 14+ foreground service requirement)
- IncomingCallActivity: add AtomicBoolean guard on handleAccept/handleDecline
  to prevent double-tap from triggering multiple service starts

---------

Co-authored-by: diegolmello <diegolmello@users.noreply.github.com>
Co-authored-by: Pierre Lehnen <55164754+pierre-lehnen-rc@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant