Repository navigation
docs(android): ringing through the Calls SDK and Push Notifications SDK - #561
hritika-cometchat wants to merge 9 commits into
Conversation
…cations SDK Android calling no longer signals through the Chat SDK. The Calls SDK 5.1 creates, joins and ends calls; the Push Notifications SDK 2.0 calls module rings the device in every app state; the UI Kit hosts the screens. Calls SDK - Rewrite ringing.mdx for the Calls SDK-only flow (initiateCall, prepared session events, IncomingCallListener, answer/decline/cancel/end, group calls) - Rewrite voip-calling.mdx as "Push Ringing" (PNConfiguration, FCM service, answer activity, readiness, busy, missed calls, own ring screen, MANUAL) - Add migrating-from-legacy-ringing.mdx with the method-by-method mapping - setup: 5.1 version, host overrides, push dependencies, one-shot init - events: getActiveSession, onParticipantConnected, incoming-call and login listeners; actions/overview/custom-control-panel: leave(); migration guide: 5.0 to 5.1 section; troubleshooting rows UI Kit - Rewrite calling-integration.mdx; add ongoing-call.mdx (answer activity) - call-features, incoming-call (deprecated), outgoing-call, call-buttons, call-logs updated for the new flow - getting-started, methods, sound-manager, troubleshooting, llms, upgrading and color-resources edits (no extra dependency, logout, ring-screen colours) Notifications: rewrite android-push-notifications.mdx for Push SDK 2.0. Chat SDK v5: deprecation notes on calling-overview and the Call Listener. docs.json: two new nav entries. Versions are the planned public releases (calls 5.1.0, push 2.0.0, UI Kit 6.1.0); hold the merge until they are published. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Automations to automatically generate PRs for you. |
… from Ringing Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… SDK calling is superseded not deprecated, real call event names, getting-started parity
…ing migration setting
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…DK internals The UI Kit has no Push SDK dependency, so the answer activity is a small app class that builds the call with CallRingingUtils.buildIncomingCall and opens CometChatOngoingCallActivity. Fix incoming-call to use real APIs. Remove MANUAL mode, token registrar options, diagnostics, decline-queue and identifier details. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…omingCallTheme) The Push SDK's incoming-call screen can now be themed in code, light and dark, and the UI Kit can pass its own theme to it. The docs still said there was no runtime theme API and listed six colour resources. - Push Ringing: setIncomingCallTheme in the setter table; the theming section now covers CometChatPNIncomingCallTheme (Mode, Colors, Kotlin and Java), saving across a killed process, the theme -> resource -> default order, and all eleven colour resources with their setters. Notes that the class is not the @style/CometChatPNIncomingCallTheme window style. - Push Notifications: setIncomingCallTheme row. - UI Kit calling integration: CometChatTheme.getIncomingCallTheme() and Compose incomingCallTheme(), the app's mapping function, the one-line setIncomingCallTheme, and which UI Kit colour feeds each field. - Color resources: eleven colours with the UI Kit colour, light and dark. - Incoming Call (deprecated): CometChatIncomingCallStyle -> theme field map, including what has no equivalent. - Call features: incoming call paragraph. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Checked every page in this PR against calls-core prepare-session-flow (Calls SDK 5.1.0-beta.2), push-notifications-sdk-android release/2.0 (2.0.0-beta.3) and uikit-android ENG-39907-ringing-v2-incoming. Dependencies and setup - The UI Kit brings the Calls SDK only; no library module depends on the Push SDK. Getting Started (3 pages), Call Features and Calling Integration now say so, and Calling Integration's Gradle snippets add both push artifacts (UI Kit listed first, so its ring colours win). - UI Kit minSdk is 28, not 26. - Permissions: RECORD_AUDIO, CAMERA and POST_NOTIFICATIONS already merge in from the Calls SDK, the UI Kit and the calls module; pages now say "request at runtime" instead of "declare". - Push init runs in Application.onCreate on every start, before login: login/logout token registration only runs in a process where init ran. - setProviderId is required; setNotificationSmallIcon covers chat notifications only and defaults to a system icon. - Logout: a Chat logout unregisters the token; only a Calls logout stops a ring. Calls SDK - getActiveSession() is @nullable: Kotlin samples use ?. and the page explains registering after join or through CallSession.getInstance(). - A prepared session that expires (5 min) reports onConnectionClosed, not onSessionTimedOut; samples and tables updated. - Callee end reasons include `ended`; treat unknown reasons as "over". - joinSession ignores settings on a prepared session (callee settings are the Push SDK's). - The caller has no ring timer: recommend one, since nothing else ends a ring the callee never received for 5 minutes. - initiateCall accepts RECEIVER_TYPE_GROUP; group decline/busy is local. - A second init() with a different app ID re-initialises. - CometChatCallsConstants has been deprecated since 5.0. Push ringing samples - setShowWhenLocked/setTurnScreenOn guarded for API 27 (calls module minSdk is 26). - The answer activity is no longer singleTop in the manifest, and onNewIntent relaunches with FLAG_ACTIVITY_NEW_TASK only, as the UI Kit's CometChatOngoingCallActivity does; singleTop routed the relaunch back to the same instance. - Custom ring screen gets its manifest entry. UI Kit events - CometChatCallEvent.CallRejected fires only for End or the 45 s timer; CallEnded only when this device hangs up a call opened with a Call. - Compose CometChatIncomingCall: onAcceptClick runs after the default accept; use onAcceptRequested to answer through the Push SDK. - setOnError / onError take one parameter. - CometChatCallActivity cannot be the Push SDK's incoming-call activity. - initiateUserCall fails with CALL_IN_PROGRESS; ACTIVE_CALL is Call Buttons'. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e-check docs(android): correct the ringing pages against the SDK source (for #561)
honey-cometchat
left a comment
There was a problem hiding this comment.
The answer-activity samples call setShowWhenLocked / setTurnScreenOn (API 27+) without a working fallback, while the pages say minSdk 26:
- In
ringing.mdxthe calls are unguarded, so the sample crashes on Android 8.0. - In
voip-calling.mdxthey're guarded, but nothing covers API 26.
The suggestions below copy the pattern the Push SDK already uses in its own ring screen (IncomingCallActivity.showOverKeyguard()): setShowWhenLocked on 27+, FLAG_SHOW_WHEN_LOCKED | FLAG_TURN_SCREEN_ON on 26.
| setShowWhenLocked(true) | ||
| setTurnScreenOn(true) |
There was a problem hiding this comment.
Calling setShowWhenLocked / setTurnScreenOn directly crashes on Android 8.0 (NoSuchMethodError) and fails lint (NewApi). Both methods are API 27+, and this page says minSdk 26.
The Push SDK's own ring screen guards them and falls back to window flags on API 26 (IncomingCallActivity.kt, showOverKeyguard()). Suggest doing the same here:
| setShowWhenLocked(true) | |
| setTurnScreenOn(true) | |
| if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) { | |
| setShowWhenLocked(true) | |
| setTurnScreenOn(true) | |
| } else { | |
| @Suppress("DEPRECATION") | |
| window.addFlags( | |
| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED or | |
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON | |
| ) | |
| } |
| setShowWhenLocked(true); | ||
| setTurnScreenOn(true); |
There was a problem hiding this comment.
Same issue in the Java tab: both methods are API 27+, so this crashes on Android 8.0.
| setShowWhenLocked(true); | |
| setTurnScreenOn(true); | |
| if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) { | |
| setShowWhenLocked(true); | |
| setTurnScreenOn(true); | |
| } else { | |
| getWindow().addFlags( | |
| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | |
| | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON); | |
| } |
| if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) { // the manifest attributes cover 27+ | ||
| setShowWhenLocked(true) | ||
| setTurnScreenOn(true) | ||
| } |
There was a problem hiding this comment.
The version check is right, but the comment isn't. The android:showWhenLocked / android:turnScreenOn manifest attributes are also API 27+, so on Android 8.0 nothing puts this screen over the lock screen. Suggest adding the window-flag fallback, as the Push SDK's own IncomingCallActivity does:
| if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) { // the manifest attributes cover 27+ | |
| setShowWhenLocked(true) | |
| setTurnScreenOn(true) | |
| } | |
| if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) { | |
| setShowWhenLocked(true) | |
| setTurnScreenOn(true) | |
| } else { | |
| @Suppress("DEPRECATION") | |
| window.addFlags( | |
| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED or | |
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON | |
| ) | |
| } |
The one-line versions at lines 329 and 363 need the same else branch.
| if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) { // the manifest attributes cover 27+ | ||
| setShowWhenLocked(true); | ||
| setTurnScreenOn(true); | ||
| } |
There was a problem hiding this comment.
Same as the Kotlin tab: add the API 26 fallback.
| if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) { // the manifest attributes cover 27+ | |
| setShowWhenLocked(true); | |
| setTurnScreenOn(true); | |
| } | |
| if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) { | |
| setShowWhenLocked(true); | |
| setTurnScreenOn(true); | |
| } else { | |
| getWindow().addFlags( | |
| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | |
| | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON); | |
| } |
honey-cometchat
left a comment
There was a problem hiding this comment.
The caller's answer handler can join the session more than once. onParticipantJoined fires again for each group member who answers, for a callee who reconnects, and for an answer that arrives after a cancel or timeout. A second joinSession rejoins the caller mid-call.
The inline suggestions add one ringing flag, shared by the join handler, Cancel and Ring timeout. With it, the caller joins once, and only while the call is still ringing. It also replaces the answered variable the Ring timeout sample uses but never declares.
| // The callee answered: now the caller joins. | ||
| override fun onParticipantJoined(participant: Participant) { | ||
| if (participant.uid == me) return | ||
| joinCallSession(call.sessionId, call.type) | ||
| } |
There was a problem hiding this comment.
onParticipantJoined can fire more than once, and joinSession has no "already joined" check:
- Group calls: it fires for every member who answers.
- 1:1 reconnect: it fires again if the callee drops and rejoins.
- Echoed events: participant events can be delivered again once the caller is in the call.
- Late answer: it can arrive after the caller cancelled or timed out.
A second joinSession doesn't find the prepared session (the first join used it), so it fetches a new token and mounts a second call view, which drops and rejoins the caller mid-call.
Suggest a ringing flag on the activity (private var ringing = true, set when initiateCall succeeds), so the caller joins once and only while the call is still ringing:
| // The callee answered: now the caller joins. | |
| override fun onParticipantJoined(participant: Participant) { | |
| if (participant.uid == me) return | |
| joinCallSession(call.sessionId, call.type) | |
| } | |
| // The callee answered: now the caller joins. This can fire again (another | |
| // group member answers, the callee reconnects, or an answer arrives after a | |
| // cancel or timeout), so join only once and only while still ringing. | |
| override fun onParticipantJoined(participant: Participant) { | |
| if (participant.uid == me || !ringing) return | |
| ringing = false | |
| joinCallSession(call.sessionId, call.type) | |
| } |
The Cancel and Ring timeout samples then use the same flag (see the comments there).
| // The callee answered: now the caller joins. | ||
| @Override | ||
| public void onParticipantJoined(Participant participant) { | ||
| if (participant.getUid().equals(me)) return; | ||
| joinCallSession(call.getSessionId(), call.getType()); | ||
| } |
There was a problem hiding this comment.
Same in the Java tab. ringing must be a field here, because a local can't be changed from inside the anonymous listener (private boolean ringing = true;).
| // The callee answered: now the caller joins. | |
| @Override | |
| public void onParticipantJoined(Participant participant) { | |
| if (participant.getUid().equals(me)) return; | |
| joinCallSession(call.getSessionId(), call.getType()); | |
| } | |
| // The callee answered: now the caller joins. This can fire again (another | |
| // group member answers, the callee reconnects, or an answer arrives after a | |
| // cancel or timeout), so join only once and only while still ringing. | |
| @Override | |
| public void onParticipantJoined(Participant participant) { | |
| if (participant.getUid().equals(me) || !ringing) return; | |
| ringing = false; | |
| joinCallSession(call.getSessionId(), call.getType()); | |
| } |
| Log.d(TAG, "Joined call session") | ||
| } | ||
|
|
||
| fun cancelOutgoingCall(sessionId: String) { |
There was a problem hiding this comment.
Following on from the join guard: set ringing = false at the start of a cancel. That way an answer that lands after the cancel is ignored, which is what the note below this sample asks for. The code currently doesn't do it.
| fun cancelOutgoingCall(sessionId: String) { | |
| fun cancelOutgoingCall(sessionId: String) { | |
| if (!ringing) return // already answered, cancelled or timed out | |
| ringing = false // a late onParticipantJoined is now ignored |
| @Override | ||
| public void onError(CometChatException e) { | ||
| Log.e(TAG, "Failed to join: " + e.getMessage()); | ||
| void cancelOutgoingCall(String sessionId) { |
There was a problem hiding this comment.
Same for the Java tab:
| void cancelOutgoingCall(String sessionId) { | |
| void cancelOutgoingCall(String sessionId) { | |
| if (!ringing) return; // already answered, cancelled or timed out | |
| ringing = false; // a late onParticipantJoined is now ignored |
| <Tab title="Kotlin"> | ||
| ```kotlin | ||
| handler.postDelayed({ | ||
| if (!answered) { |
There was a problem hiding this comment.
answered isn't declared or set anywhere on the page. Using the same ringing flag fixes two things:
- The timer becomes a no-op once the call is answered.
- A timeout that fires after the caller already cancelled no longer sends a second
endCallwithunanswered.
| if (!answered) { | |
| if (ringing) { | |
| ringing = false |
| <Tab title="Java"> | ||
| ```java | ||
| handler.postDelayed(() -> { | ||
| if (!answered) { |
There was a problem hiding this comment.
Same for the Java tab:
| if (!answered) { | |
| if (ringing) { | |
| ringing = false; |
Summary
Android calling no longer signals through the Chat SDK. The Calls SDK 5.1 creates, joins and ends calls; the Push Notifications SDK 2.0 calls module rings the device in every app state (foreground, background, killed); the UI Kit hosts the screens. This PR updates every Android page that described the old flow and adds the two pages the new flow needs.
Consumer-facing wording is "ringing" and "legacy ringing"; the pages never say v1 or v2.
Calls SDK (
calls/android/)ringing.mdxrewritten: Calls SDK-only flow with a sequence diagram,CometChatCalls.initiateCall, prepared-session events ("ringing…" / answered),addIncomingCallListenerwith the reason table, answer from the answer activity, decline, cancel, ring timeout, end withleave(), call waiting, group calls, logout, status values.voip-calling.mdxrewritten as Push Ringing (slug kept, no redirect): dependencies,PNConfigurationsetter table, three-line FCM service, answer activity, permissions andensureRingReady/getDiagnostics/verifyPushSetup, how a ring ends, call during a call, missed calls, killed-app behaviour, staging hosts, tokens, own incoming-call screen, theming resources, MANUAL mode, troubleshooting.migrating-from-legacy-ringing.mdx(new, in the Migration Guide nav group): before/after diagrams, seven migration steps, a 16-row method mapping table, caller and callee screens before/after, checklist.setup: 5.1 version, push dependencies, one-shot init warning.events:getActiveSession,onParticipantConnected, prepared-session semantics, Incoming Call and Login listener sections.actions,overview,custom-control-panel:leave().migration-guide-v5: 5.0 → 5.1 section.troubleshooting: six ringing rows.UI Kit (
ui-kit/android/)calling-integration.mdxrewritten: five steps (dependencies,setEnableCalling, push config withsetAnswerActivity(CometChatOngoingCallActivity), permissions, logout), what the kit does from there, own-screen calls, ring-screen colours, upgrade pointer.ongoing-call.mdx(new, in the Components nav): the in-call screen and Push SDK answer activity.call-features,incoming-call(deprecated, kept forsetIncomingCallActivity),outgoing-call(call states,endReason, ViewModel members),call-buttons,call-logsupdated for the new flow.getting-started,getting-started-kotlin/-jetpack(no extra dependency,6.1.0),methods(new settings, logout behaviour),sound-manager,troubleshooting(16 calling rows),llms-android-v6,upgrading-from-v5(Ringing table),color-resources(sixcometchat_pn_call_*resources).Notifications and Chat SDK
notifications/android-push-notifications.mdxrewritten for Push SDK 2.0: automatic tokens,PNConfiguration, inline reply and tap listener, badge count kept app-side; VoIP/ConnectionService and manual-token sections removed.sdk/android/v5/calling-overviewandv5/real-time-listeners: notes that the Chat SDK calling APIs andCallListenerare superseded by the Calls SDK (deprecation lands with a coming Chat SDK release).Before merging
calls-sdk-android:5.1.0,push-notifications-android/push-notifications-calls-android:2.0.0, UI Kit6.1.0. Do not merge before they are published.api(Getting Started and Calling Integration say no extra dependency is needed).sample-app-kotlin-push/sample-app-compose-push; the notifications page links to the repository root.@Deprecatedannotations ships, change that wording to "deprecated".mint dev(links verified by file existence only).Related: ENG-39907.
🤖 Generated with Claude Code