Skip to content

refactor(llc): move the call's ringing into CallRingingController - #1438

Draft
renefloor wants to merge 2 commits into
feat/flu-856-ringing-call-coordinatorfrom
feat/flu-863-call-ringing-controller
Draft

renefloor wants to merge 2 commits into
feat/flu-856-ringing-call-coordinatorfrom
feat/flu-863-call-ringing-controller

Conversation

@renefloor

Copy link
Copy Markdown
Contributor

Fixes FLU-863

Part of FLU-859 · 23/26, stacked on #1437

What changed

CallRingingController (lib/src/call/ringing/, @internal) rings a Call. Call.accept and Call.reject delegate to it.

  • Moved out of Call:
    • accept and reject;
    • the call.accepted and call.rejected handlers, which reject locally when the user answered on another device;
    • the wait for a ring to be answered;
    • the outgoing ring state poller (_startRingStatePollingIfNeeded, _onPolledRingState, _stopRingStatePolling).
  • The cross-call steps of accept (cancel the user's outgoing ring of another call, and leave the active call unless several may be active) are RingingCallCoordinator.prepareToAccept, the C1 coordinator. It returns null when there is nothing to clear. The accept then marks the call accepted in the same turn, as before; call_accept_test pins that.
  • The wait stops when the call is left. It used to be state.firstWhere(...).timeout(...), which _untilLeft only abandoned. A ring the caller cancelled kept the timeout running and logged [awaitIncomingToBeAccepted] failed: TimeoutException 25 s later, for a call that was already gone (seen on a Pixel 8 while testing A7). The controller's wait takes a left future from the connection coordinator. When it completes, the wait cancels its timer and state subscription and ends with null, and the join ends as cancelled.
  • _awaitCallToBeJoined is deleted. Its branch waited for CallStatusJoining, which only lifecycleCallJoining sets, and nothing calls that. This is the TODO the ticket mentions.
  • The ringing bookkeeping on leave and dispose (clearCallAcceptedOnThisDevice, releaseRingingCall) is CallRingingController.release(), called from _clear and _releaseUnjoined.

Decisions to check

  • The ring state poller moved too. The ticket doesn't list it, but it is the outgoing half of the same ring and was the last ringing code in Call.
  • end stays on Call. The ticket lists it, but since A4 it is a one-line delegate to the connection coordinator, which owns the end. A ringing controller would only forward it.
  • The incoming and outgoing call writes in _clear's finally stay where they are. _clear matches the outgoing call by cid and _releaseUnjoined by identity. Moving them into one method would pick one rule, which is a behaviour change outside this ticket.
  • The timeout error message changed from Future not completed to No answer within <timeout>. It is still a TimeoutException wrapped the same way, and still ends the join as an unanswered ring.

Tests

  • New: test/src/call/ringing/call_ringing_controller_test.dart (5):
    • for an incoming and an outgoing ring: the wait stops when the call is left, with no timeout error logged afterwards;
    • for an incoming and an outgoing ring: an unanswered ring fails the join with one timeout error, and no coordinator join is made;
    • an incoming ring accepted during the wait joins.
  • New in ringing_call_coordinator_test:
    • accept cancels the user's outgoing ring of another call;
    • when nothing is replaced, the call is marked accepted in the same turn.
  • Mutation check: settling the wait on leave without cancelling the timer fails both "stops when the call is left" tests.
  • Results:
    • stream_video: 1298 passed;
    • stream_video_push_notification: 67;
    • stream_video_flutter without goldens: 729.

🤖 Generated with Claude Code

@coderabbitai

coderabbitai Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

@codecov

codecov Bot commented Oct 8, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 91.01124% with 16 lines in your changes missing coverage. Please review.
✅ Project coverage is 44.40%. Comparing base (f04dd8f) to head (4b7be44).

Files with missing lines Patch % Lines
.../lib/src/call/ringing/call_ringing_controller.dart 88.88% 15 Missing ⚠️
packages/stream_video/lib/src/call/call.dart 94.11% 1 Missing ⚠️
Additional details and impacted files
@@                            Coverage Diff                            @@
##           feat/flu-856-ringing-call-coordinator    #1438      +/-   ##
=========================================================================
+ Coverage                                  44.28%   44.40%   +0.12%     
=========================================================================
  Files                                        421      422       +1     
  Lines                                      31472    31481       +9     
=========================================================================
+ Hits                                       13937    13979      +42     
+ Misses                                     17535    17502      -33     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@renefloor
renefloor added this pull request to stack #1442 October 9, 2026 06:12
renefloor and others added 2 commits October 9, 2026 14:22
Accept, reject, the accept and reject events, the wait for a ring to be
answered and the ring state poller move out of Call. The wait now stops
with the call instead of running out its timer, and the cross-call steps
of accept move to StreamVideo.ringing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@renefloor
renefloor force-pushed the feat/flu-863-call-ringing-controller branch from 4b7be44 to 830ca9a Compare October 9, 2026 12:27

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant