Skip to content

fix(voip): auto-decline second incoming call as busy#7284

Open
diegolmello wants to merge 3 commits into
feat.voip-lib-newfrom
fix/voip-pr6918-03-busy-decline-on-second-call
Open

fix(voip): auto-decline second incoming call as busy#7284
diegolmello wants to merge 3 commits into
feat.voip-lib-newfrom
fix/voip-pr6918-03-busy-decline-on-second-call

Conversation

@diegolmello
Copy link
Copy Markdown
Member

@diegolmello diegolmello commented Apr 30, 2026

Proposed changes

When a second incoming-call FCM push arrives while IncomingCallActivity is already showing the first caller, Android delivers the new Intent to the existing singleInstance Activity via onNewIntent. Without an override the activity's intent pointer silently shifts to the new call, so if the user taps Accept they answer the wrong caller.

This fix overrides onNewIntent to handle the two cases correctly:

  • Different call ID: silently declines the new call with a busy reason via VoipNotification.rejectBusyCall, leaving the on-screen UI untouched.
  • Same call ID (rapid retry by the same caller): refreshes caller info, rebinds buttons, and reschedules the ring timeout.

Issue(s)

Related to PR #6918 — blocker B4 (busy-decline on second incoming call).

How to test or reproduce

  1. Have two devices (A and B) call the same callee simultaneously, a few seconds apart.
  2. Callee sees device A's full-screen incoming-call UI throughout the second ring.
  3. Device B receives a busy response from the server; the callee's UI never switches.
  4. A single caller rapidly retrying refreshes the UI correctly without leaking timeout handlers.

Screenshots

N/A — no visual change; the on-screen UI remains unchanged for the primary caller.

Types of changes

  • Bugfix (non-breaking change which fixes an issue)

Checklist

  • I have read the CONTRIBUTING doc
  • I have signed the CLA
  • Lint and unit tests pass locally with my changes
  • I have added tests that prove my fix is effective or that my feature works (if applicable)
  • I have added necessary documentation (if applicable)
  • Any dependent changes have been merged and published in downstream modules

Summary by CodeRabbit

  • Bug Fixes
    • Incoming-call handling improved when the call screen is already displayed: new incoming calls for a different call are rejected as busy to avoid conflicts.
    • Repeated incoming-call attempts for the same call now refresh the on-screen UI, reattach controls, and reschedule ring timeouts so retry storms don’t leave stale timers or broken buttons.

When a second caller rings while IncomingCallActivity is already visible,
the singleInstance delivery via onNewIntent previously left the activity's
intent pointer mismatched, risking answering the wrong call. The override
now silently rejects the new call as busy without touching the on-screen UI.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 30, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a0052c47-c440-4d2e-8e43-fdddbf78f46d

📥 Commits

Reviewing files that changed from the base of the PR and between cf4f5e9 and d0fe2cd.

📒 Files selected for processing (1)
  • android/app/src/main/java/chat/rocket/reactnative/voip/IncomingCallActivity.kt
📜 Recent review details
🔇 Additional comments (1)
android/app/src/main/java/chat/rocket/reactnative/voip/IncomingCallActivity.kt (1)

308-346: onNewIntent handling looks solid and aligns with the busy-decline design.

The updated flow correctly separates different-call busy rejection from same-call refresh, and the accept/decline guard prevents timeout/UI refresh races while an action is already in progress.


Walkthrough

Adds onNewIntent override to IncomingCallActivity to handle incoming call intents while the activity is running. It parses the intent into a VoipPayload, validates it, rejects different callId calls as busy, or refreshes the current call state, UI, and timeout for valid payloads.

Changes

Cohort / File(s) Summary
IncomingCallActivity Intent Handling
android/app/src/main/java/chat/rocket/reactnative/voip/IncomingCallActivity.kt
Added onNewIntent override to parse incoming call intents, validate VoipPayload, reject calls with a different callId as busy via VoipNotification.rejectBusyCall, or refresh the current call UI/state and reschedule ring timeout for matching or new payloads.

Sequence Diagram

sequenceDiagram
    participant Android as Android System
    participant Activity as IncomingCallActivity
    participant Payload as VoipPayload
    participant Notif as VoipNotification
    participant UI as UI/Buttons

    Android->>Activity: onNewIntent(intent)
    Activity->>Payload: parse intent -> VoipPayload?
    alt invalid payload
        Activity->>Activity: log debug, return
    else valid payload
        alt existing voipPayload && payload.callId != current.callId
            Activity->>Notif: rejectBusyCall(callId)
            Notif-->>Activity: rejection sent
        else new or same callId
            Activity->>Activity: set voipPayload
            Activity->>UI: updateUI()
            Activity->>UI: setupButtons()
            Activity->>Activity: scheduleTimeout()
        end
    end
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Suggested labels

type: bug

🚥 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 accurately summarizes the main change: adding onNewIntent override to auto-decline a second incoming call as busy when the activity is already displaying a first caller.
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.


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
Review rate limit: 7/8 reviews remaining, refill in 7 minutes and 30 seconds.

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

@diegolmello diegolmello temporarily deployed to experimental_android_build April 30, 2026 18:26 — with GitHub Actions Inactive
@diegolmello diegolmello had a problem deploying to experimental_ios_build April 30, 2026 18:26 — with GitHub Actions Error
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@android/app/src/main/java/chat/rocket/reactnative/voip/IncomingCallActivity.kt`:
- Around line 331-338: In onNewIntent / the refresh path, avoid re-arming the
call timeout when user action has already started by checking the
acceptDeclineGuard before calling scheduleTimeout; wrap the
scheduleTimeout(newPayload) call in a conditional like if (!acceptDeclineGuard)
{ scheduleTimeout(newPayload) } (leave updateUI and setupButtons as-is so UI
updates still occur).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3c41e1e8-993c-4501-ae9b-972e69bdd746

📥 Commits

Reviewing files that changed from the base of the PR and between 7ea0877 and cf4f5e9.

📒 Files selected for processing (1)
  • android/app/src/main/java/chat/rocket/reactnative/voip/IncomingCallActivity.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 comments (1)
android/app/src/main/java/chat/rocket/reactnative/voip/IncomingCallActivity.kt (1)

320-329: Good isolation of second-call handling.

This branch correctly keeps the current UI state intact and rejects only the new call as busy, which matches the blocker’s intended behavior.

@diegolmello diegolmello had a problem deploying to official_android_build April 30, 2026 20:32 — with GitHub Actions Error
@diegolmello diegolmello had a problem deploying to experimental_ios_build April 30, 2026 20:32 — with GitHub Actions Error
@diegolmello diegolmello temporarily deployed to experimental_android_build April 30, 2026 20:32 — with GitHub Actions Inactive
@diegolmello diegolmello requested a deployment to approve_e2e_testing April 30, 2026 20:49 — with GitHub Actions Waiting
@diegolmello diegolmello temporarily deployed to experimental_android_build April 30, 2026 20:55 — with GitHub Actions Inactive
@diegolmello diegolmello requested a deployment to official_android_build April 30, 2026 20:55 — with GitHub Actions Waiting
@diegolmello diegolmello requested a deployment to experimental_ios_build April 30, 2026 20:55 — with GitHub Actions Waiting
@diegolmello diegolmello requested a deployment to upload_experimental_android April 30, 2026 21:31 — with GitHub Actions Waiting
@github-actions
Copy link
Copy Markdown

Android Build Available

Rocket.Chat Experimental 4.72.0.108745

Internal App Sharing: https://play.google.com/apps/test/RQVpXLytHNc/ahAO29uNRMN_1Cvalw-VMhsCkgdb2fL1CmlRwnvXqxzrIFKjrPiApaCtFlaoP4tEw_XNxegrAW_1kgPs3u2zKBh9t-

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