cometchat-android-v6-calls — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited cometchat-android-v6-calls (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Ground truth: catalogandroid-v6.json+features.android-v6.json(voice-video-calls) +contracts.android-v6.json(voice-video-calls) + the live pagescalling-integration,call-features,components/{call-buttons,incoming-call,outgoing-call,call-logs},guide-call-log-details. Deep Calls-SDK behavior: the/calls/androiddocs tree. Verify symbols against the catalog; fetch params from docs; never trust memory.
cometchat-android-v6-core — install, credentials (assets/cometchat-settings.json), initFromSettings → login → render, sizing (references/layout.md), the fetch map. Assumed here, never repeated.cometchat-android-v6-{kotlin,compose}-placement — where the incoming-call surface sits in the app shell."add voice/video calling", "show call buttons in the chat", "handle incoming calls", "add a call history screen", "the call buttons aren't appearing", "call log details".
Add the Calls SDK alongside your cohort's UI Kit artifact (never instead of it):
dependencies {
implementation("com.cometchat:chatuikit-compose-android:6.0.5") // or chatuikit-kotlin-android for XML Views
implementation("com.cometchat:calls-sdk-android:5.0.4")
}⚠️ REQUIRED whenever `android.enableJetifier=true` (which `core` mandates for the Chat SDK's pre-AndroidX transitive) — add a Jetifier ignore-list, or the build breaks the moment you add calling.calls-sdk-android5.0.x bundles a React-Native stack (react-android/hermes/react-native-webrtc), and Jetifier cannot transformreact-android-*.aar— so with Jetifier on, the build dies atcheckDebugAarMetadatawithExecution failed for JetifyTransform: react-android-0.77.2-debug.aar(the app compiled fine BEFORE calling; adding the artifact breaks it — verified 2026-09-10). These AARs are already AndroidX, so exclude them from Jetifier ingradle.properties: ``properties android.jetifier.ignorelist=react-android,hermes-android,react-native-webrtc``
⚠️ The artifact and the flag are a PAIR — setting either alone breaks the app.
· flagtrue, artifact missing → app crashes at launch (initFromSettings→initCometChatCalls→NoClassDefFoundError: CometChatCalls$SessionSettingsBuilder) · artifact present, flagfalse→ calling components crash when used (RuntimeException: Please call the CometChatCalls.init() method …)
>
⚠️ BOTH are required — the artifact alone is not enough. uiKit.enableCalling: true inassets/cometchat-settings.json is what makes initFromSettings initialize CometChatCalls. Without it, CometChatCallLogs throws RuntimeException: Please call the CometChatCalls.init() method …; without the artifact it throws NoClassDefFoundError. Both compile fine — device-only failures (verified 2026-08-21).
The kit auto-detects the Calls SDK and activates calling. Also set "uiKit": { "enableCalling": true } in app/src/main/assets/cometchat-settings.json so CometChatUIKit.initFromSettings(...) initializes the Calls SDK through the telemetry-aware path (it auto-inits Calls when that flag is on). Dashboard: calling must be enabled for the app.
Header call buttons differ BY COHORT (verified vs installed 6.0.5 source):
CometChatMessageHeader's voice/video button visibility defaults follow CallsUtils.isCallingEnabled(), so the buttons render with no extra code once calling is enabled.CometChatMessageHeader composable defaults hideVoiceCallButton = true and hideVideoCallButton = true. Pass both explicitly: CometChatMessageHeader(user = user, hideVoiceCallButton = false, hideVideoCallButton = false)And do NOT use the header's auxiliaryView slot for other icons — it REPLACES the default auxiliary area that hosts the call buttons (they vanish). Extra header icons go in trailingView (see cometchat-android-v6-compose-components).
hideVoiceCallButton = false, hideVideoCallButton = false — see above).⚠️ Enabling calling in an app with EXISTING sessions — force a fresh login.CometChatUIKit.login()short-circuits when the same uid is already logged in (persisted session): it returnsonSuccessWITHOUT callingloginCometChatCalls, so the Calls SDK never gets an auth token (verified vs 6.0.5CometChatUIKit.ktlogin + on device 2026-08-25). Symptom:CometChatCallLogsshows a silent error state; logcat saysUser auth token cannot be null. When calling is FIRST enabled on an app whose users already have a session, users must re-login —CometChatUIKit.logout(...)thenCometChatUIKit.login(...)(or force a fresh login path once, e.g. on a calling-feature version bump). During development, wireonErroronCometChatCallLogsso this failure is not silent.
Application subclass, registering before the UI Kit is used:import com.cometchat.chat.core.Call // NOTE: chat.core, NOT chat.models
import com.cometchat.chat.core.CometChat
class BaseApplication : Application() {
companion object {
private val LISTENER_ID = "${BaseApplication::class.java.simpleName}${System.currentTimeMillis()}"
}
override fun onCreate() {
super.onCreate()
CometChat.addCallListener(LISTENER_ID, object : CometChat.CallListener() {
override fun onIncomingCallReceived(call: Call) { /* show CometChatIncomingCall over the current screen */ }
override fun onOutgoingCallAccepted(call: Call) { /* proceed to the ongoing-call surface */ }
override fun onOutgoingCallRejected(call: Call) { /* dismiss the outgoing UI */ }
override fun onIncomingCallCancelled(call: Call) { /* dismiss the incoming UI */ }
})
}
}Register the Application class in the manifest (android:name=".BaseApplication"). Views: instantiate CometChatIncomingCall(context), set its call, set fitsSystemWindows = true, wire its error handler, and present it (dialog / full-screen overlay). Compose: hold the incoming Call in app-level state and render the incoming-call composable above your nav host — fetch the composable's params from components/incoming-call.md.
CAMERA and RECORD_AUDIO at runtime before a call starts (video needs both; audio-only needs RECORD_AUDIO); declare them in the manifest. The kit ships CometChatPermissionHandler / CometChatPermissionActivity — prefer them over a hand-rolled flow.ℹ️ SoLoader / bundled React-Native native libs (know this before an ACTIVE call).calls-sdk-android5.0.x bundles a React-Native stack (react-android/hermes/react-native-webrtc), declared at `runtime` scope in its POM — so they land on the runtime classpath andinitFromSettingscalls-init +CometChatCallLogswork with no extra deps (verified on device: init succeeds, call logs render). An active call surface loads those native.sos, which on RN ≥ 0.76 depend onSoLoader. If an active call fails to open with aSoLoader/UnsatisfiedLinkError/NoClassDefFoundError(React/JSI/ Hermes symbols), add the RN + SoLoader artifacts on the compile classpath and init SoLoader once inApplication.onCreatebefore the first call surface: ``kotlin // build.gradle.kts (only if an active call throws a SoLoader/native-link error) implementation("com.facebook.react:react-android:0.77.2") // match what calls-sdk-android pulls implementation("com.facebook.soloader:soloader:0.12.1") // Application.onCreate: SoLoader.init(this, OpenSourceMergedSoMapping)`` Whether 5.0.x needs this for an active call is not yet settled from a single device — it is NOT needed for init or call logs. Verify with a real two-device call; treat this as the fix if (and only if) you hit that native-link error, not as an unconditional step.
CometChatCallButtons (auto-rendered in the message header; can also be placed standalone) · CometChatIncomingCall (ringing UI — accept/decline) · CometChatOutgoingCall (dialing UI) · CometChatOngoingCall + CometChatOngoingCallActivity / CometChatCallActivity (the in-call surface) · CometChatCallLogs (call history list) + CometChatCallLogsListItem · call bubbles in the message list: CometChatCallActionBubble, CometChatMeetCallBubble · CometChatCallEvent (call events → cometchat-android-v6-events). SDK-side (build-your-own flows): CometChat.initiateCall / acceptCall / rejectCall / getActiveCall / clearActiveCall / addCallListener / removeCallListener — see core/references/docs-map.md → SDK section.
The minimum for "add calling" (contract voice-video-calls): initiate (buttons) + incoming-call UI + outgoing-call UI + call logs. A call button with no incoming-call handler is a dead end — the callee never sees the ring.
// Minimum calls surface — four components for voice-video-calls contract
// CometChatCallButtons: auto-rendered in the message header; place standalone when needed
val callButtons = CometChatCallButtons(context)
// CometChatOutgoingCall: shown while the callee hasn't answered yet
val outgoingCall = CometChatOutgoingCall(context)
outgoingCall.call = pendingCall
// CometChatCallActivity / CometChatOngoingCallActivity: the in-call surface, launched
// automatically during a session. ⚠️ You do NOT declare these — BOTH are already declared in the
// UI-Kit AAR manifest and merge in automatically (verified vs 6.0.x). The cohort-correct classes:
// Compose: com.cometchat.uikit.compose.calls.CometChatCallActivity
// com.cometchat.uikit.compose.presentation.ongoingcall.ui.CometChatOngoingCallActivity
// Views: com.cometchat.uikit.kotlin.calls.CometChatCallActivity
// com.cometchat.uikit.kotlin.presentation.ongoingcall.ui.CometChatOngoingCallActivity
// (There is NO `com.cometchat.chatuikit.calling.*` class in v6 — that's a v5/v4-era name; do not
// add a manual <activity> line for it or the merge/launch breaks.)
// CometChatCallLogs: call history tab
val callLogs = CometChatCallLogs(context)| Intent | Page (append .md) |
|---|---|
| calling overview / what's supported | /ui-kit/android/call-features |
| call buttons props | /ui-kit/android/call-buttons |
| incoming / outgoing UI props | /ui-kit/android/incoming-call · /ui-kit/android/outgoing-call |
| call logs + details recipe | /ui-kit/android/call-logs · /ui-kit/android/guide-call-log-details |
| custom in-call UI, layouts, recording, screen share, audio modes | the /calls/android/* pages (call-layouts, custom-control-panel, audio-modes, background-handling, idle-timeout, events, …) |
Importing com.cometchat.chat.models.Call (it is `com.cometchat.chat.core.Call` — the wrong import compiles to an "Unresolved reference 'Call'" cascade) · manually declaring CometChatCallActivity/CometChatOngoingCallActivity in your manifest (they AUTO-MERGE from the UI-Kit AAR — a hand-written <activity> with the wrong/legacy com.cometchat.chatuikit.calling.* name breaks the launch) · Calls SDK missing (buttons never appear) · enableCalling not set in the settings file · Compose header without hideVoiceCallButton = false / hideVideoCallButton = false (buttons never appear — Compose defaults hide them) · Compose auxiliaryView used for a custom header icon (it replaces the call-button host — use trailingView) · calling enabled on an app with a persisted session without a re-login (Calls SDK tokenless — call logs silently error with "User auth token cannot be null") · no global call listener (incoming calls never ring) · listener registered per-Activity only (rings only on that screen) · registering in Application but forgetting android:name in the manifest · missing runtime CAMERA/RECORD_AUDIO permissions (call fails silently) · calling before login resolves · call UI not fitsSystemWindows / not full-bleed (controls under system bars) · leaking the listener (remove it if you register outside Application) · mixing a v4/v5 calls artifact with the v6 kit.
Compile against the pinned kit (./gradlew :app:assembleDebug # in YOUR app (npm run verify:fences:android-v6 is a pack-repo gate)). On device (TWO devices/emulators + two users — calling can't be verified single-ended): call buttons render in the message header; tapping starts an outgoing call; the OTHER device rings with the incoming UI from any screen; accept → ongoing call with audio/video; decline/cancel dismisses cleanly on both sides; the call appears in CometChatCallLogs and as a call bubble in the chat. No ring ⇒ listener not registered globally (or app not logged in). Permission denial ⇒ handle it and tell the user, don't fail silently.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.