fix(voip): use call ID for Telecom handle URI to prevent crash on Android 12+#7280
Conversation
…roid 12+ Caller display names containing spaces or '@' caused Uri.fromParts to produce an invalid URI, making TelecomManager throw IllegalArgumentException on Android 12 and later. Using the call UUID for the URI's user-info component avoids this; the human-readable name now flows via EXTRA_CALLER_DISPLAY_NAME, which Telecom handles separately and surfaces on the lockscreen and in-call UI.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📜 Recent review details🧰 Additional context used🧠 Learnings (2)📓 Common learnings📚 Learning: 2026-04-22T22:57:58.545ZApplied to files:
🔇 Additional comments (2)
WalkthroughRegistration for incoming VoIP calls now requires a non-empty Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Suggested labels
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. 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. Review rate limit: 5/8 reviews remaining, refill in 22 minutes and 29 seconds.Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
android/app/src/main/java/chat/rocket/reactnative/voip/VoipNotification.kt (1)
774-776: ⚡ Quick winHarden the
callIdguard to reject blank values.Line 774 uses
isEmpty(), so whitespace-only IDs still pass and can flow into Telecom handle creation. PreferisBlank()here to fail earlier on malformed payloads.Proposed patch
- if (callId.isEmpty()) { - Log.e(TAG, "Cannot register call with TelecomManager: callId is empty") + if (callId.isBlank()) { + Log.e(TAG, "Cannot register call with TelecomManager: callId is blank") return }🤖 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/VoipNotification.kt` around lines 774 - 776, The guard checking callId should reject blank values: in VoipNotification (where callId is validated before TelecomManager handle creation) replace the callId.isEmpty() check with callId.isBlank() so whitespace-only IDs are treated as invalid and trigger the early return (keeping the Log.e(TAG, ...) and return flow intact) to prevent malformed payloads from reaching Telecom registration.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@android/app/src/main/java/chat/rocket/reactnative/voip/VoipNotification.kt`:
- Around line 774-776: The guard checking callId should reject blank values: in
VoipNotification (where callId is validated before TelecomManager handle
creation) replace the callId.isEmpty() check with callId.isBlank() so
whitespace-only IDs are treated as invalid and trigger the early return (keeping
the Log.e(TAG, ...) and return flow intact) to prevent malformed payloads from
reaching Telecom registration.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 345b7573-382f-4890-bb4e-3d14de4415f8
📒 Files selected for processing (1)
android/app/src/main/java/chat/rocket/reactnative/voip/VoipNotification.kt
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: ESLint and Test / run-eslint-and-test
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: CR
Repo: RocketChat/Rocket.Chat.ReactNative PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-22T22:57:58.545Z
Learning: Applies to app/lib/services/voip/**/*.{ts,tsx} : Implement VoIP features in app/lib/services/voip/ directory using Zustand stores for WebRTC peer-to-peer audio calls with native CallKit (iOS) and Telecom (Android) integration
📚 Learning: 2026-04-22T22:57:58.545Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat.ReactNative PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-22T22:57:58.545Z
Learning: Applies to app/lib/services/voip/**/*.{ts,tsx} : Implement VoIP features in app/lib/services/voip/ directory using Zustand stores for WebRTC peer-to-peer audio calls with native CallKit (iOS) and Telecom (Android) integration
Applied to files:
android/app/src/main/java/chat/rocket/reactnative/voip/VoipNotification.kt
🔇 Additional comments (1)
android/app/src/main/java/chat/rocket/reactnative/voip/VoipNotification.kt (1)
797-812: Nice fix: separating URI handle from display name is the right approach.Using
callIdforEXTRA_INCOMING_CALL_ADDRESSandcallerforEXTRA_CALLER_DISPLAY_NAMEcleanly addresses Android 12+ Telecom URI validation without changing JS-facing extras.
That constant is not part of the public Telecom API, so the previous commit broke the Android build. The human-readable display name still reaches the system: it travels through the in-app EXTRA_CALLER_NAME extra, which the call-keep VoiceConnection constructor reads and applies via Connection.setCallerDisplayName(), so Telecom surfaces it on the lockscreen and in-call UI as required.
|
Android Build Available Rocket.Chat Experimental 4.72.0.108726 Internal App Sharing: https://play.google.com/apps/test/RQVpXLytHNc/ahAO29uNQ6Cn53Mrq8W71JWGoKZlGQ2LQQvZWg32EhV8CmvZSGJ1-7X279bVNrEmbWIm25Q7X7ricJklMu6QXOs2ji |
Proposed changes
Caller display names containing spaces,
@, or other special characters causedUri.fromParts(PhoneAccount.SCHEME_TEL, caller, null)to produce an invalid URI. On Android 12 and later,TelecomManager.addNewIncomingCallvalidates the handle URI strictly and throwsIllegalArgumentException, crashing the incoming-call registration.This fix uses the call's UUID (
callId) as the URI's user-info component — a string that is always URI-safe — while the human-readable caller name is forwarded to Telecom viaEXTRA_CALLER_DISPLAY_NAME. Telecom surfaces this extra on the lockscreen and the full-screen incoming-call UI without validating it as a URI component.The existing in-app extras consumed by react-native-callkeep (
EXTRA_CALLER_NAME,name,handle) are unchanged so JavaScript-side call handling is unaffected.Issue(s)
Fixes incoming-call crash when caller's display name contains a space or
@on Android 12, 13, and 14 (blocker B1 in PR #6918).How to test or reproduce
IllegalArgumentExceptionis logged.@(e.g. "alice@example").Screenshots
N/A — no UI change; crash fix only.
Types of changes
Checklist
Further comments
EXTRA_CALLER_DISPLAY_NAMEis aTelecomManagerconstant available since API 18 — no new permission or min-SDK change required.Summary by CodeRabbit