Skip to content

fix(llc): fix noise cancellation breaking on iOS after rejoin reconnection flow#1234

Merged
Brazol merged 4 commits into
mainfrom
fix/noise-cancellation-rejoin
May 29, 2026
Merged

fix(llc): fix noise cancellation breaking on iOS after rejoin reconnection flow#1234
Brazol merged 4 commits into
mainfrom
fix/noise-cancellation-rejoin

Conversation

@Brazol
Copy link
Copy Markdown
Contributor

@Brazol Brazol commented May 28, 2026

Summary by CodeRabbit

  • Bug Fixes

    • Noise cancellation no longer breaks on iOS after rejoining, migration, or reconnection.
    • Audio processing is reliably re-enabled after reconnect/rejoin or migration when it was previously active.
    • Noise-cancellation state and behavior persist across reconnections and bitrate/profile switches.
  • Tests

    • Added comprehensive tests covering audio-processing start/stop, auto-on behavior, reconnection re-binding, teardown, and bitrate/profile transitions.

Review Change Stack

@Brazol Brazol requested a review from a team as a code owner May 28, 2026 12:35
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 28, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8c122e04-08dd-473d-8238-a57957bcc106

📥 Commits

Reviewing files that changed from the base of the PR and between b5fddfe and b506b1c.

📒 Files selected for processing (2)
  • packages/stream_video/CHANGELOG.md
  • packages/stream_video/lib/src/call/call.dart
✅ Files skipped from review due to trivial changes (1)
  • packages/stream_video/CHANGELOG.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/stream_video/lib/src/call/call.dart

📝 Walkthrough

Walkthrough

Preserve the iOS native audio filter across WebRTC pipeline restarts and re-enable Dart-side audio processing after rejoin/migration; add extensive tests for start/stop, auto-on join, re-bind after reconnect, teardown, and bitrate-profile interactions; update changelog.

Changes

iOS Audio Noise Cancellation Restoration

Layer / File(s) Summary
iOS audio filter lifecycle preservation
packages/stream_video_noise_cancellation/ios/.../StreamAudioFilterCapturePostProcessingModule.swift
setAudioFilter() checks filter identity before releasing and skips unnecessary cleanup. audioProcessingRelease() becomes a no-op to preserve the filter reference across WebRTC capture pipeline restarts so audioProcessingInitialize() can re-arm noise cancellation on subsequent calls.
Dart audio processing re-binding after rejoin/migration & tests
packages/stream_video/lib/src/call/call.dart, packages/stream_video/CHANGELOG.md, packages/stream_video/test/src/call/call_audio_processing_test.dart
During Call._join completion, audio processing is conditionally re-enabled when a rejoin or migration occurs and audio processing was configured and previously active. Adds comprehensive tests covering start/stop, auto-on join, re-bind after reconnect, teardown, and setAudioBitrateProfile interactions; documents the fix in the changelog.

Estimated code review effort:
🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs:

  • GetStream/stream-video-flutter#1237: Modifies join/reconnect completion paths related to fast-reconnect and publisher-connection safety checks; related at the reconnect/join lifecycle level.

Suggested reviewers:

  • renefloor

"I hop through wires and audio streams so bright,
I guard the filter through each rejoin night,
I nudge the Dart to wake the noise-cancel art,
So iOS silence sings, and echoes keep their heart. 🐇🎧"

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The pull request has no description provided, missing all required sections from the template including Goal, Implementation details, Testing, and Contributor Checklist. Add a complete PR description following the template with at least Goal, Implementation details, and Testing sections to explain the changes.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main fix: noise cancellation breaking on iOS after rejoin reconnection flow, which is the primary objective of the changeset.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
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.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/noise-cancellation-rejoin

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 and usage tips.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 28, 2026

Actionable comments posted: 0

@codecov
Copy link
Copy Markdown

codecov Bot commented May 28, 2026

Codecov Report

❌ Patch coverage is 62.50000% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 9.01%. Comparing base (ae162f8) to head (b506b1c).

Files with missing lines Patch % Lines
packages/stream_video/lib/src/call/call.dart 62.50% 3 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff            @@
##            main   #1234      +/-   ##
========================================
+ Coverage   8.88%   9.01%   +0.12%     
========================================
  Files        676     676              
  Lines      49577   49585       +8     
========================================
+ Hits        4407    4469      +62     
+ Misses     45170   45116      -54     

☔ View full report in Codecov by Sentry.
📢 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.

Copy link
Copy Markdown

@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 current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/stream_video/test/src/call/call_audio_processing_test.dart`:
- Around line 660-668: The test uses fixed sleeps (Duration.zero,
Duration(milliseconds: 200)) around internetStatusController.add(...) and then
asserts verify(() => mockStreamVideo.setAudioProcessingEnabled(true)), which can
race with the retry backoff/jitter defined in retry_policy.dart; replace the
fixed waits with a polling/wait-until that asserts the mock call within a
generous timeout (e.g., repeatedly check verify(() =>
mockStreamVideo.setAudioProcessingEnabled(true)) or use a test helper that waits
until the condition is true) after triggering the rejoin path via
internetStatusController, so the test waits deterministically for
mockStreamVideo.setAudioProcessingEnabled to be invoked rather than relying on
fragile sleep durations.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: f15aced0-5a86-4e34-91b1-54b84faa0eaa

📥 Commits

Reviewing files that changed from the base of the PR and between 4c80e2e and 6e7e8ce.

📒 Files selected for processing (1)
  • packages/stream_video/test/src/call/call_audio_processing_test.dart

Comment thread packages/stream_video/test/src/call/call_audio_processing_test.dart Outdated
Copy link
Copy Markdown

@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

🧹 Nitpick comments (1)
packages/stream_video/test/src/call/call_audio_processing_test.dart (1)

693-722: 💤 Low value

Consider slightly longer waits for negative assertions on slow CI.

Lines 717 and 744 use fixed 100ms waits before verifyNever to confirm the rebind does not occur. While acceptable for negative assertions, 100ms may be marginal on busy CI runners where the async reconnect chain could be delayed. A 200–500ms wait would reduce the (low) risk of a false-negative flake if the rebind logic is slow to evaluate the guard conditions.

Minor robustness tweak
 internetStatusController.add(InternetStatus.disconnected);
 await Future<void>.delayed(Duration.zero);
 internetStatusController.add(InternetStatus.connected);
-await Future<void>.delayed(const Duration(milliseconds: 100));
+await Future<void>.delayed(const Duration(milliseconds: 200));

 // Still no calls — processing was not active so nothing to rebind
 verifyNever(() => mockStreamVideo.setAudioProcessingEnabled(any()));

Apply the same change at line 744.

Also applies to: 724-748

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/stream_video/test/src/call/call_audio_processing_test.dart` around
lines 693 - 722, Increase the short fixed waits used before negative assertions
to reduce flakiness on slow CI: in the test 'does not rebind when audio
processing was not active' update the two delays that currently use const
Duration(milliseconds: 100) (after adding InternetStatus.connected and the other
occurrence noted in the comment) to a longer value (e.g., 300ms) so the async
reconnect chain has more time to run before calling verifyNever(() =>
mockStreamVideo.setAudioProcessingEnabled(any())); keep the same test flow and
targets (internetStatusController events and verifyNever against
mockStreamVideo.setAudioProcessingEnabled).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/stream_video/test/src/call/call_audio_processing_test.dart`:
- Around line 46-65: The helper _waitForMockCall currently checks
verify(mockCall).called(greaterThanOrEqualTo(1)), causing false positives for
later expected invocations; change _waitForMockCall to accept an int
expectedCount parameter (default 1) and use
verify(mockCall).called(equals(expectedCount)) (or
greaterThanOrEqualTo(expectedCount) if you want leniency), then update all call
sites that expect multiple invocations (e.g., the rebind/rejoin verification) to
pass the correct expectedCount so the helper waits until the desired number of
calls have occurred.

---

Nitpick comments:
In `@packages/stream_video/test/src/call/call_audio_processing_test.dart`:
- Around line 693-722: Increase the short fixed waits used before negative
assertions to reduce flakiness on slow CI: in the test 'does not rebind when
audio processing was not active' update the two delays that currently use const
Duration(milliseconds: 100) (after adding InternetStatus.connected and the other
occurrence noted in the comment) to a longer value (e.g., 300ms) so the async
reconnect chain has more time to run before calling verifyNever(() =>
mockStreamVideo.setAudioProcessingEnabled(any())); keep the same test flow and
targets (internetStatusController events and verifyNever against
mockStreamVideo.setAudioProcessingEnabled).
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: edd5a841-6b5b-4352-a8a0-974feb3a056e

📥 Commits

Reviewing files that changed from the base of the PR and between 6e7e8ce and b5fddfe.

📒 Files selected for processing (1)
  • packages/stream_video/test/src/call/call_audio_processing_test.dart

Comment thread packages/stream_video/test/src/call/call_audio_processing_test.dart
@Brazol Brazol merged commit 2ffb34a into main May 29, 2026
12 of 16 checks passed
@Brazol Brazol deleted the fix/noise-cancellation-rejoin branch May 29, 2026 06:36
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.

2 participants