chore: sync with upstream livekit/client-sdk-flutter (v2.8.0) keeping our audio fixes#2
Closed
td-famedly wants to merge 19 commits into
Closed
chore: sync with upstream livekit/client-sdk-flutter (v2.8.0) keeping our audio fixes#2td-famedly wants to merge 19 commits into
td-famedly wants to merge 19 commits into
Conversation
I noticed the example's color scheme was out of date. So, I pulled in a bunch of colors from https://github.com/livekit-examples/agent-starter-react, made some small design updates to the button + text field, and swapped in the more modern LiveKit logo. Definitely a lot more that could be done here, I was aiming for "better" not "perfect". ## Screenshots <img width="596" height="830" alt="Screenshot 2026-05-15 at 12 46 11 PM" src="https://github.com/user-attachments/assets/c9436e79-023e-41f5-b053-a6d96109440c" /> <img width="513" height="713" alt="Screenshot 2026-05-15 at 12 46 39 PM" src="https://github.com/user-attachments/assets/974bf3e4-ea85-4784-a0b5-b0873eb636e0" />
Bump PB for PacketTrailer related features
…ls in example application (livekit#1057) This PR fixes an issue in the Android example application where the device screen turns off automatically during an active video call due to screen timeout. ### **Problem** During an ongoing LiveKit call on Android, the screen is not kept awake, which leads to: - Poor user experience during video calls - Interrupted visibility when no user interaction occurs ### **Solution** This PR adds native Android window flag handling in MainActivity to ensure the screen remains active while a call is in progress: - Uses native flags to prevent screen timeout - Uses native flags as well to handle lock screen visibility ### **The flags are:** - **Enabled** when the room is active - **Cleared** when the room is disposed --------- Co-authored-by: Hiroshi Horie <548776+hiroshihorie@users.noreply.github.com>
## Summary Align Flutter's generated default lower screen-share simulcast layer with the common SDK behavior. This updates the default generated lower layer to: - use half resolution - keep the top layer's frame rate - use `max(150kbps, topLayerBitrate / 4)` - carry through explicit bitrate/network priorities Also aligns the `screenShareH720FPS5` and `screenShareH1080FPS30` preset bitrates with the common SDK values. ## Notes This does not add the JS-only screen-share presets such as `h360fps15`, `h720fps30`, or `original`; that broader preset parity work should be handled separately. ## Tests - `dart format --set-exit-if-changed lib/src/types/video_parameters.dart lib/src/utils.dart test/utils_test.dart` - `flutter test test/utils_test.dart` - `flutter analyze --no-pub lib/src/types/video_parameters.dart lib/src/utils.dart test/utils_test.dart`
## Summary - Suppress the C++/WinRT experimental coroutine deprecation error for `permission_handler_windows_plugin`. - Keeps the example Windows build working on the `windows-2025-vs2026` GitHub Actions image. - Shorten Build workflow job names so checks render as `Build / Android`, `Build / Dart Analyze`, etc. ## Testing - `git diff --check` - Parsed `.github/workflows/build.yaml` with Ruby YAML.
## Summary - Port Swift SDK simulcast lower-layer clamping behavior to Flutter. - Clamp lower-layer max framerate so it does not exceed the configured top layer. - Clamp lower-layer bitrate only when the layer does not actually downscale resolution. - Use the larger output dimension when computing simulcast scale-down values. - Add coverage for clamp behavior, ladder length, unchanged presets, priority preservation, and computed encodings. ## Testing - `dart format --output=none --set-exit-if-changed lib/src/types/video_parameters.dart lib/src/utils.dart test/utils_test.dart` - `flutter test test/utils_test.dart` - `flutter analyze --no-pub lib/src/types/video_parameters.dart lib/src/utils.dart test/utils_test.dart`
) ## Summary Previously, `setVideoQuality` / `setVideoDimensions` on a remote track were **ignored** (with a warning) whenever `adaptiveStream` was enabled. This PR adopts the JS SDK's approach instead: the manual preference is **merged** client-side with the dimensions derived from the visible views, and the **smaller (more conservative)** of the two is sent to the server. Along the way it fixes a few related correctness issues in the adaptive-stream path. The logic mirrors `client-sdk-js`'s `RemoteTrackPublication` (`isEnabled`, `emitTrackUpdate`, `areDimensionsSmaller`, `layerDimensionsFor`). ## Changes **Manual quality + adaptive stream merge** - `setVideoQuality` / `setVideoDimensions` / `setVideoFPS` are no longer rejected when adaptive stream is on; the request is merged with the visibility-derived dimensions, smaller area wins (matching JS `areDimensionsSmaller`, strict `<`). - When only a quality is requested, it's compared against that quality's simulcast layer dimensions before deciding which to send. **Explicit enable/disable overrides visibility** - Enable/disable state is modeled as an internal tri-state (`TrackEnabledPreference`: unset / enabled / disabled), mirroring JS's `requestedDisabled`. - An explicit `enable()` / `disable()` now always wins over adaptive-stream visibility. Previously the visibility timer computed `disabled` independently and silently ignored the user's request. **Debounce correctness** - A manual update cancels any pending debounced visibility update, and the debounced send rebuilds settings from current state at fire time — so a stale snapshot can't clobber a newer manual update. **Misc** - `fps` is now preserved across adaptive-stream visibility updates (previously dropped). - Adaptive-stream visibility state is reset when the track changes, so stale dimensions can't leak into a later update. - Merge/disable/build logic extracted into pure functions (`resolveVideoSettings`, `resolveDisabled`, `buildUpdateTrackSettings`) in `track_settings.dart`. ## Tests - Unit tests for the pure resolution/build logic: merge precedence, equal-area tie-break, tri-state disable, and proto building. - Publication-level test asserting the `UpdateTrackSettings` actually sent to the signal client for `enable()` / `disable()`.
The adaptive-stream visibility observer fed each view's logical (DIP) size straight to the server, so on retina/HiDPI displays it under-requested by the device pixel ratio and the server returned an upscaled/soft layer. Server layers are sized in physical pixels. - Add `AdaptiveStreamPixelDensity` (`auto` | `fixed(double)`) mirroring the JS SDK's `pixelDensity` option, plus `VideoTrackRenderer.adaptiveStreamPixelDensity` (default: `auto`), set per view rather than room-wide. Fractional densities are supported and the resolved value is capped at 3x to bound bandwidth. - Track each rendered view with a `VideoTrackViewRegistration` that owns both the `GlobalKey` and pixel density, so density updates stay tied to the renderer lifecycle. - Resolve auto mode from each view's `devicePixelRatio` via `MediaQuery.maybeDevicePixelRatioOf`; fixed modes use a constant multiplier. - `_computeVideoViewVisibility` scales each view's logical size by the resolved density, materializes the visible sizes once per tick, and requests the largest scaled dimensions across all views.
* Added: Session API support for simpler E2EE setup * Changed: Manual video quality selection can be used with adaptive stream enabled * Changed: Generated protocol definitions for LiveKit protocol v1.45.8 * Fixed: waitForBufferStatusLow busy-waiting after engine close * Fixed: Simulcast lower layers exceeding the top layer * Fixed: forceRelay log message interpolation * Fixed: sendSyncState error handling so sync-state preparation failures are not swallowed * Fixed: Screen share simulcast default low layer alignment * Fixed: Region failover null-provider dereference * Fixed: Android builds with dependencies that require compileSdk 36 * Fixed: Deferred track listener leaks across reconnects * Fixed: Adaptive stream dimensions on high-density displays * Fixed: Session.start() reentrancy during concurrent calls * Fixed: Connected server address resolving from the wrong peer connection * Fixed: Reconnect counter null assertion on the first reconnect attempt * Fixed: Premature publication disposal during unpublish
…ivekit#1106) ## Summary - Align Flutter default local-video degradation behavior with the Swift SDK. - Default unset `VideoPublishOptions.degradationPreference` to `maintainResolution` for camera and screen-share publishing. - Keep explicit degradation preferences overrideable by apps. ## Context Related to livekit#1097, which explores preserving video quality through a live-streaming option. This PR takes the smaller SDK-default approach instead: use maintain-resolution by default, matching Swift, without adding a separate app-facing toggle for this behavior. ## Testing - `dart analyze` - `flutter test test/core/room_e2e_test.dart`
## Summary Migrates the Android plugin to AGP 9's built-in Kotlin while keeping older toolchains building (same pattern as flutter-webrtc/flutter-webrtc#2075): - Apply the **Kotlin Gradle Plugin only when built-in Kotlin is inactive** — AGP < 9, or AGP 9 with `android.builtInKotlin=false` (the configuration Flutter currently ships by default while the ecosystem migrates). When AGP 9's built-in Kotlin is active it registers the `kotlin` extension itself and rejects KGP, so applying it is skipped. - Set the JVM target through the `kotlin { compilerOptions {} }` DSL **when the extension supports it** (KGP 1.9+ / AGP 9 built-in Kotlin), falling back to the legacy `kotlinOptions` DSL for apps still on KGP 1.8.x. - Bump the standalone buildscript fallback KGP to 2.1.0 so it is self-consistent. - Add a changeset entry for the generated release notes. ## Context AGP 9 uses built-in Kotlin support and rejects Android plugins that still apply KGP directly. This follows the Flutter compatibility migration path instead of raising the minimum supported toolchain. ## Verification - Example app builds (`flutter build apk --debug`) on the current stable toolchain (AGP 8.x + modern KGP path). - The AGP 9 built-in path mirrors the reviewed and merged flutter-webrtc implementation.
…ead-back (livekit#1107) ## What Runtime control of audio processing (AEC / NS / AGC / HPF) for local audio tracks, plus an engine-wide diagnostic read-back, built on the WebRTC-SDK audio processing options API (webrtc-sdk/webrtc#247 + webrtc-sdk/webrtc#254). ## API **Set** — `AudioProcessingOptions` with per-component enabled flags and modes (`automatic` / `platform` / `software`), applied either at capture time via `AudioCaptureOptions` or at runtime: ```dart final result = await localAudioTrack.setAudioProcessingOptions(options); ``` Caller bugs (invalid combination, remote track) throw `AudioProcessingException`; legitimate outcomes return a typed `AudioProcessingApplyResult` (`applied` / `stored` / rejections). **Read** — the audio processing module is owned by the native peer connection factory and shared engine-wide, so the snapshot lives on `AudioManager`: ```dart final state = await AudioManager.instance.getAudioProcessingState(); ``` Per component: `requested` (nullable — null means nothing was ever applied), `isSoftwareResolved` / `isSoftwareActive`, `isPlatformAvailable` / `isPlatformResolved` / `isPlatformActive`, and `effective` as the merged verdict. Same requested → resolved → active → effective vocabulary as the native SDKs. ## Commits Bottom-up, each builds standalone: 1. `chore(deps)`: WebRTC-SDK pin bump 2. Dart `AudioProcessingOptions` for `LocalAudioTrack` 3. Routing through the LiveKit native plugin (iOS + Android handlers) 4. Typed apply results 5. Engine-wide v2 state read-back on `AudioManager` ## Dependencies / not yet done - **Lib pin is still `144.7559.08`** — will bump to `144.7559.09` (which carries the state v2 API from webrtc-sdk/webrtc#254) once published. The state read-back native code requires `.09` to compile. - **Android requires `FlutterWebRTCPlugin.getPeerConnectionFactory()`** — flutter-webrtc/flutter-webrtc#2077. - Device smoke test on iOS + Android pending the `.09` artifacts.
## Summary - Add `deployment` field to `RoomAgentDispatch` for targeting specific agent deployments - Add `agentDeployment` to `TokenRequestOptions` to pass deployment through token requests - Update generated JSON serialization code The `deployment` field allows targeting a specific agent deployment (e.g., "staging"). Leave empty to target the production deployment. Related PRs: - node-sdks: livekit/node-sdks#675 - python-sdks: livekit/python-sdks#722 - rust-sdks: livekit/rust-sdks#1176 - client-sdk-swift: livekit/client-sdk-swift#1043 - client-sdk-js: livekit/client-sdk-js#1971 ## Usage ```dart final options = TokenRequestOptions( roomName: 'my-room', agentName: 'my-agent', agentDeployment: 'staging', // Optional: target specific deployment ); ``` Or directly via `RoomAgentDispatch`: ```dart final dispatch = RoomAgentDispatch( agentName: 'my-agent', metadata: 'my-metadata', deployment: 'staging', ); ``` ## Test plan ### Unit Tests ```bash flutter test flutter test test/token/token_source_test.dart -v ``` ### Manual Verification **1. Verify JSON serialization includes deployment:** ```dart final dispatch = RoomAgentDispatch( agentName: 'my-agent', deployment: 'staging', ); final json = dispatch.toJson(); print(json); // Should include 'deployment': 'staging' ``` **2. Verify TokenRequestOptions converts to request correctly:** ```dart final options = TokenRequestOptions( roomName: 'test-room', agentName: 'my-agent', agentDeployment: 'staging', ); final request = options.toRequest(); print(request.roomConfiguration?.agents?.first?.deployment); // Should print 'staging' ``` **3. Verify JSON round-trip:** ```dart final original = RoomAgentDispatch( agentName: 'my-agent', deployment: 'staging', ); final json = original.toJson(); final restored = RoomAgentDispatch.fromJson(json); assert(restored.deployment == 'staging'); ``` ### End-to-End Verification 1. Use TokenSource to get credentials with agentDeployment set 2. Connect to room - agent with matching deployment should join 3. Verify only staging agent receives the dispatch 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
## What Adds first-class, process-wide audio session and routing control through `AudioManager` on iOS and Android. LiveKit owns the platform audio session by default, while apps that need exact platform behavior can switch to manual mode and apply typed session configs. ## API and behavior - **Automatic by default**: calls need no setup. LiveKit applies a managed communication policy. - **iOS automatic mode**: the native WebRTC audio-engine delegate drives `AVAudioSession` from engine lifecycle events. Listen-only playout uses `playback`; recording uses `playAndRecord`. - **Android automatic mode**: LiveKit uses a communication session through the new AudioSwitch-backed `LKAudioSwitchManager`. - **Manual mode**: `setAudioSessionOptions(...)` and `deactivateAudioSession()` switch `AudioManager` to manual mode. `setAudioSessionManagementMode(AudioSessionManagementMode.automatic)` hands lifecycle control back to LiveKit. - **Typed options**: `AudioSessionOptions.communication()` and `AudioSessionOptions.media()` pre-fill Apple and Android configs, with per-platform overrides applied verbatim in manual mode. - **Speaker routing**: `AudioManager.instance.setSpeakerOutputPreferred(...)` owns speaker preference and forced speaker routing. Wired and Bluetooth devices still win unless `force: true`. ## Compatibility - Existing calls keep working without audio-session setup. - `Hardware` audio members and `Room.setSpeakerOn(...)` are deprecated forwarders to `AudioManager`. - `flutter_webrtc` native audio-session management is disabled so LiveKit has one owner for the session. - `bypassVoiceProcessing` now only controls WebRTC voice processing; it no longer changes the session intent. ## Docs and tests - Adds `docs/audio.md` and updates the README audio sections. - Adds coverage for session options, automatic/manual mode transitions, Apple/Android policy resolution, routing serialization, and engine-state observation. - Verified locally with `dart analyze`, `flutter test test/audio/audio_session_test.dart`, and `flutter test --reporter compact`.
## Summary - move create-time audio processing setup into the local capture start path so publish/preconnect prepares platform audio processing before WebRTC opens the microphone, matching the Swift SDK flow - keep `LocalAudioTrack.setAudioProcessingOptions` as a command-style runtime API that returns on success and throws `AudioProcessingException` on failure - expose structured failure reasons for invalid combinations, unavailable platform support, native apply failures, and unknown failures - clean up local audio tracks when capture/publish startup fails and keep cleanup failures from masking the original error - bump `flutter_webrtc` to `1.5.2` for Android audio device module access ## Behavior - `LocalAudioTrack.create(...)` stores requested audio processing options; it no longer attempts to apply them immediately. - `track.start()` starts local capture and applies stored processing options before the microphone opens on supported platforms. - Publish and preconnect paths fail during capture start if the exposed native platform API reports audio processing setup failure. - Runtime `setAudioProcessingOptions(...)` still applies immediately for active local audio tracks and throws on failed native apply/store. - Android uses `JavaAudioDeviceModule.prewarmRecording(options)`. That WebRTC API returns `void`, so this PR can surface thrown failures, but clean internal `false` returns from `initRecordingIfNeeded()` / `prewarmRecordingIfNeeded()` are not observable until WebRTC/flutter_webrtc exposes a resultful API. ## Testing - `flutter pub get` - `flutter pub get` in `example` - `flutter analyze --no-pub` - `flutter test --no-pub` - `flutter build apk --debug --no-pub` in `example` - Android emulator smoke test: example joined a room, published local microphone audio, muted/unpublished, and showed no ADM/platform-unavailable errors
## Summary - Add `LiveKitClient.initialize(initialAudioSessionOptions: ...)` for Android WebRTC audio-device initialization. - Seed Android automatic audio-session policy from the same initial options so playback-first apps do not need to immediately call `AudioManager.setAudioSessionOptions(...)` with the same preset. - Rename the playback preset to `AudioSessionOptions.mediaPlayback()` for clearer intent. - Avoid sticky Android speaker routing when updating speaker preference. - Update audio session docs and change entry. ## Runtime behavior Android uses `AudioSessionOptions` in two places with different timing: | API | Timing | What changes | | --- | --- | --- | | `LiveKitClient.initialize(initialAudioSessionOptions: ...)` | Before WebRTC initializes. | Passes Android audio configuration into flutter_webrtc/WebRTC ADM creation. This is where WebRTC playout `AudioAttributes` such as `usageType` and `contentType` are set. It also seeds LiveKit's automatic Android session policy. | | `AudioManager.instance.setAudioSessionOptions(...)` | Runtime. | Replaces LiveKit's stored session policy, switches to manual management, and applies LiveKit's platform session behavior: Android audio mode, audio focus mode, stream type, focus ownership, routing handler policy, and iOS category/options/mode. | The important Android limitation is that WebRTC playout `AudioAttributes` are still initialization-time configuration. Calling `AudioManager.setAudioSessionOptions(...)` at runtime applies LiveKit's platform session policy, but it does not mutate the `AudioAttributes` on an already-created WebRTC audio device module. For playback-first Android apps that need media volume/routing from WebRTC playout, pass `AudioSessionOptions.mediaPlayback()` to `LiveKitClient.initialize(...)` before connecting. ## Validation - `flutter test --no-pub test/audio/audio_session_test.dart` - `flutter analyze --no-pub --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
…for all video codecs (livekit#1120) ## Summary - Apply `x-google-start-bitrate` SDP hint to all video codecs (VP8, VP9, AV1, H264, H265), not just SVC codecs - Use 90% of target bitrate as start bitrate to prevent initial blurriness - Degradation preference already defaults to `maintainResolution` ## Problem Video starts blurry for 5-15 seconds before improving. This is caused by WebRTC's bandwidth estimator starting at ~300kbps and slowly ramping up to the target bitrate. ## Solution **x-google-start-bitrate**: Tell WebRTC to start at 90% of target bitrate instead of ramping up from ~300kbps. Applied consistently to all video codecs. Note, The PR only addresses the x-google-start-bitrate fix (changing from SVC-only to all video codecs, and using 0.9 multiplier) - The maintainResolution default was already in place in Flutter SDK, so no change was needed for that part ## Test plan - [ ] Verify video quality is sharp from the start when publishing - [ ] Test with VP8, VP9, H264, AV1 codecs - [ ] Verify bandwidth estimator adapts properly if network can't handle the start bitrate 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
…m-v2.8.0-85f9 Co-authored-by: td <td-famedly@users.noreply.github.com>
|
|
|
Caution Breaking change detected without major changeset
If this is intentional, please add a changeset with |
…ng-track queue The fork's EngineTrackAddedEvent handler added a blocking retry loop that re-looked-up the remote participant up to 5x (1s apart) when a track arrived before the participant's metadata was known. Upstream already handles this race via _pendingTrackQueue.enqueue + _flushPendingTracks, which subscribes early-arriving tracks immediately once the participant appears. The retry loop awaited before enqueuing, defeating upstream's queue and adding up to 5s of latency. It also broke the upstream e2e test 'tracks arriving before participant metadata are handled once metadata arrives' (1s timeout). Remove the retry loop and rely on the queue. The [audioElementLogs] diagnostics are kept (incl. the 'will enqueue for later' warning). Co-authored-by: td <td-famedly@users.noreply.github.com>
Member
Author
|
maybe we just go back to upstream |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Merges the latest changes from upstream
livekit/client-sdk-fluttermaininto our fork, preserving our custom diagnostics/fixes. This brings the fork up to upstream v2.8.0 plus subsequent fixes (17 new upstream commits since the last sync).This was done as a merge (consistent with the previous sync in #1), so our fork commits are retained and there is a single clear sync point.
What's included from upstream
17 commits merged (oldest → newest):
f211282Update example colors (Update example colors livekit/client-sdk-flutter#1086)3ec0288Update protocol to v1.45.8 (Update protocol to v1.45.8 livekit/client-sdk-flutter#1088)c5103bffix(android): prevent screen from turning off during active video calls in example application (fix(android): prevent screen from turning off during active video calls in example application livekit/client-sdk-flutter#1057)3488ba8Align screen-share simulcast default lower layer (Align screen-share simulcast default lower layer livekit/client-sdk-flutter#1089)55295dechore: fix Windows CI and tidy check names (chore: fix Windows CI and tidy check names livekit/client-sdk-flutter#1099)d83f272Clamp simulcast lower layers to top layer (Clamp simulcast lower layers to top layer livekit/client-sdk-flutter#1084)ead71caMerge manual video quality/dimensions with adaptive stream (Merge manual video quality/dimensions with adaptive stream livekit/client-sdk-flutter#1047)a05a782Fix pixel density in AdaptiveStream (Fix pixel density in AdaptiveStream livekit/client-sdk-flutter#1098)707792bv2.8.0 (v2.8.0 livekit/client-sdk-flutter#1101)b6cc65dUse maintain-resolution as the default video degradation preference (Use maintain-resolution as the default video degradation preference livekit/client-sdk-flutter#1106)d031c3fchore(android): support AGP 9 built-in Kotlin (chore(android): support AGP 9 built-in Kotlin livekit/client-sdk-flutter#1102)1c03b55feat(audio): runtime audio processing options and engine-wide state read-back (feat(audio): runtime audio processing options and engine-wide state read-back livekit/client-sdk-flutter#1107)a193401feat: add deployment field to agent dispatch (feat: add deployment field to agent dispatch livekit/client-sdk-flutter#1111)55af814feat(audio): add AudioManager session and routing APIs (feat(audio): add AudioManager session and routing APIs livekit/client-sdk-flutter#1108)d1fe342Apply audio processing options when local capture starts (Apply audio processing options when local capture starts livekit/client-sdk-flutter#1115)faa5b0bAdd Android initial audio session options (Add Android initial audio session options livekit/client-sdk-flutter#1117)6bdbc3efix: improve initial video quality by setting x-google-start-bitrate for all video codecs (fix: improve initial video quality by setting x-google-start-bitrate for all video codecs livekit/client-sdk-flutter#1120)Highlights: new
AudioManagersession & routing APIs, runtime audio-processing options, Android initial audio session options, AGP 9 support, agent-dispatchdeploymentfield, video quality/degradation improvements, and protocol bump to v1.45.8. Version bumped to2.8.0.Our fixes that are preserved
After the merge, our fork delta vs
upstream/mainis two files:lib/src/core/room.dart[audioElementLogs]diagnostics around track deferral/enqueue and participant updates._onSignalSpeakersChangedEvent/_onSignalConnectionQualityUpdateEvent/_onSignalStreamStateUpdateEventwidened toFuture<void> async.lib/src/track/web/_audio_html.dart[audioElementLogs]diagnostics instartAudiofor non-MediaStreamTrackWebtracks and non-HTMLAudioElementelements.One reconciliation (to make CI green)
The fork previously had a blocking retry loop in the
EngineTrackAddedEventhandler that re-looked-up the remote participant up to 5× (1s apart) when a track arrived before the participant's metadata was known. Upstream already solves this race with_pendingTrackQueue.enqueue+_flushPendingTracks(subscribes early-arriving tracks the moment the participant appears). The retry loopawaited before enqueuing, which defeated upstream's queue, added up to 5s of latency, and failed the upstream e2e testtracks arriving before participant metadata are handled once metadata arrives(1s timeout).That test was already failing on our pre-sync
main(e182c4b) — i.e. it's a pre-existing fork issue, not introduced by this merge. As offered in the original PR description, this PR removes the redundant retry loop and relies on upstream's queue, keeping all the[audioElementLogs]diagnostics (including the "will enqueue for later" warning). See commitf862833.Validation
Toolchain: Flutter 3.44.4 (stable) / Dart 3.12.2.
flutter analyze(whole workspace): No issues found.dart format --set-exit-if-changedon our modified files: clean.flutter test: 300 passed, 1 skipped, 0 failed. ✅ (the previously failing e2e test now passes)Notes on other CI checks (not code-fixable here)
mechtech-mind,xianshijing-lk,hiroshihorie,1egoman) whose commits came in via the merge. This is a CLA-signing/process matter for the fork, not something resolvable in code.dart-apitool) — reportsLocalParticipant.getDefaultDegradationPreferenceremoved. That's an intentional upstream API change (Use maintain-resolution as the default video degradation preference livekit/client-sdk-flutter#1106, maintain-resolution default), included via this sync; it's an informational caution, not in the failed-checks set.