Skip to content

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
mainfrom
cursor/sync-upstream-v2.8.0-85f9
Closed

chore: sync with upstream livekit/client-sdk-flutter (v2.8.0) keeping our audio fixes#2
td-famedly wants to merge 19 commits into
mainfrom
cursor/sync-upstream-v2.8.0-85f9

Conversation

@td-famedly

@td-famedly td-famedly commented Jun 30, 2026

Copy link
Copy Markdown
Member

Summary

Merges the latest changes from upstream livekit/client-sdk-flutter main into 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):

Highlights: new AudioManager session & routing APIs, runtime audio-processing options, Android initial audio session options, AGP 9 support, agent-dispatch deployment field, video quality/degradation improvements, and protocol bump to v1.45.8. Version bumped to 2.8.0.

Our fixes that are preserved

After the merge, our fork delta vs upstream/main is two files:

  • lib/src/core/room.dart
    • [audioElementLogs] diagnostics around track deferral/enqueue and participant updates.
    • _onSignalSpeakersChangedEvent / _onSignalConnectionQualityUpdateEvent / _onSignalStreamStateUpdateEvent widened to Future<void> async.
  • lib/src/track/web/_audio_html.dart
    • [audioElementLogs] diagnostics in startAudio for non-MediaStreamTrackWeb tracks and non-HTMLAudioElement elements.

One reconciliation (to make CI green)

The fork previously had a blocking retry loop in the EngineTrackAddedEvent handler 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 loop awaited before enqueuing, which defeated upstream's queue, added up to 5s of latency, and failed the upstream e2e test tracks 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 commit f862833.

Validation

Toolchain: Flutter 3.44.4 (stable) / Dart 3.12.2.

  • flutter analyze (whole workspace): No issues found.
  • dart format --set-exit-if-changed on 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)

  • CLA assistant — flags the 4 upstream commit authors (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.
  • Breaking-change check (dart-apitool) — reports LocalParticipant.getDefaultDegradationPreference removed. 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.
Open in Web Open in Cursor 

1egoman and others added 18 commits May 16, 2026 09:27
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>
@CLAassistant

CLAassistant commented Jun 30, 2026

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you all sign our Contributor License Agreement before we can accept your contribution.
0 out of 4 committers have signed the CLA.

❌ hiroshihorie
❌ xianshijing-lk
❌ 1egoman
❌ mechtech-mind
You have signed the CLA already but the status is still pending? Let us recheck it.

@github-actions

github-actions Bot commented Jun 30, 2026

Copy link
Copy Markdown

Caution

Breaking change detected without major changeset

dart-apitool detected the following breaking changes:

Preparing git repository: https://github.com/famedly/livekit-flutter-sdk
Using ref: main
Cloning git repository: https://github.com/famedly/livekit-flutter-sdk
Checking out ref: main
Successfully cloned to: /tmp/UNJWNY
Preparing package dependencies for git package https://github.com/famedly/livekit-flutter-sdk (forced Flutter)
Resolving dependencies...
Downloading packages...
  _fe_analyzer_shared 85.0.0 (104.0.0 available)
  analyzer 7.7.1 (14.0.0 available)
  build 2.5.4 (4.0.6 available)
  build_config 1.1.2 (1.3.0 available)
  build_resolvers 2.5.4 (3.0.4 available)
  build_runner 2.5.4 (2.15.0 available)
  build_runner_core 9.1.2 (9.3.2 available)
  built_value 8.12.4 (8.12.6 available)
  code_assets 1.0.0 (1.2.1 available)
  connectivity_plus 7.1.1 (7.2.0 available)
  dart_style 3.1.1 (3.1.9 available)
  dart_webrtc 1.8.0 (1.8.1 available)
  dbus 0.7.12 (0.7.14 available)
  device_info_plus 12.3.0 (13.2.0 available)
  device_info_plus_platform_interface 7.0.3 (8.1.0 available)
  flutter_webrtc 1.4.0 (1.5.2 available)
  hooks 1.0.2 (2.0.2 available)
  json_annotation 4.9.0 (4.12.0 available)
  json_serializable 6.9.5 (6.14.0 available)
  matcher 0.12.19 (0.12.20 available)
> meta 1.18.0 (was 1.17.0) (1.18.3 available)
  mockito 5.4.6 (5.7.0 available)
  native_toolchain_c 0.17.6 (0.19.2 available)
  objective_c 9.3.0 (9.4.1 available)
  package_config 2.2.0 (3.0.0 available)
  path_provider 2.1.5 (2.1.6 available)
  path_provider_android 2.2.22 (2.3.1 available)
  path_provider_linux 2.2.1 (2.2.2 available)
  path_provider_platform_interface 2.1.2 (2.1.3 available)
  source_gen 2.0.0 (4.2.3 available)
  source_helper 1.3.7 (1.3.12 available)
  synchronized 3.4.0 (3.4.1 available)
> test_api 0.7.11 (was 0.7.10) (0.7.13 available)
  vector_math 2.2.0 (2.4.0 available)
  vm_service 15.0.2 (15.2.0 available)
  win32 5.15.0 (6.3.0 available)
  win32_registry 2.1.0 (3.0.3 available)
  xml 6.6.1 (7.0.1 available)
Changed 2 dependencies!
38 packages have newer versions incompatible with dependency constraints.
Try `flutter pub outdated` for more information.
Resolving dependencies in `./example`...
Downloading packages...
Got dependencies in `./example`.
Preparing . (forced Flutter)
Copying sources from .
Preparing package dependencies for local package . (forced Flutter)
Resolving dependencies...
Downloading packages...
  _fe_analyzer_shared 85.0.0 (104.0.0 available)
  analyzer 7.7.1 (14.0.0 available)
  build 2.5.4 (4.0.6 available)
  build_config 1.1.2 (1.3.0 available)
  build_resolvers 2.5.4 (3.0.4 available)
  build_runner 2.5.4 (2.15.0 available)
  build_runner_core 9.1.2 (9.3.2 available)
  built_value 8.12.4 (8.12.6 available)
  code_assets 1.0.0 (1.2.1 available)
  connectivity_plus 7.1.1 (7.2.0 available)
  dart_style 3.1.1 (3.1.9 available)
  dart_webrtc 1.8.0 (1.8.1 available)
  dbus 0.7.12 (0.7.14 available)
  device_info_plus 12.3.0 (13.2.0 available)
  device_info_plus_platform_interface 7.0.3 (8.1.0 available)
  hooks 1.0.2 (2.0.2 available)
  json_annotation 4.9.0 (4.12.0 available)
  json_serializable 6.9.5 (6.14.0 available)
  matcher 0.12.19 (0.12.20 available)
  meta 1.18.0 (1.18.3 available)
  mockito 5.4.6 (5.7.0 available)
  native_toolchain_c 0.17.6 (0.19.2 available)
  objective_c 9.3.0 (9.4.1 available)
  package_config 2.2.0 (3.0.0 available)
  path_provider 2.1.5 (2.1.6 available)
  path_provider_android 2.2.22 (2.3.1 available)
  path_provider_linux 2.2.1 (2.2.2 available)
  path_provider_platform_interface 2.1.2 (2.1.3 available)
  source_gen 2.0.0 (4.2.3 available)
  source_helper 1.3.7 (1.3.12 available)
  synchronized 3.4.0 (3.4.1 available)
  test_api 0.7.11 (0.7.13 available)
  vector_math 2.2.0 (2.4.0 available)
  vm_service 15.0.2 (15.2.0 available)
  win32 5.15.0 (6.3.0 available)
  win32_registry 2.1.0 (3.0.3 available)
  xml 6.6.1 (7.0.1 available)
Got dependencies!
37 packages have newer versions incompatible with dependency constraints.
Try `flutter pub outdated` for more information.
Resolving dependencies in `./example`...
Downloading packages...
Got dependencies in `./example`.
Omitting pub get (package config already present)
Analyzing /tmp/UNJWNY
Omitting pub get (package config already present)
Analyzing .
Cleaning up
Cleaning up
Checking Package version
ignoring prerelease
-- Generating report using: Console Reporter --
BREAKING CHANGES
└─┬ Class LocalParticipant
  └── Method "getDefaultDegradationPreference" removed (CE10)
Non-Breaking changes
├── Interface "AudioProcessingOptions" added (CI02) (minor)
├── Interface "AudioProcessingMode" added (CI02) (minor)
├── Interface "PacketTrailerFeature" added (CI02) (minor)
├── Interface "AudioSessionOptions" added (CI02) (minor)
├── Interface "AppleAudioSessionConfiguration" added (CI02) (minor)
├── Interface "AppleAudioCategory" added (CI02) (minor)
├── Interface "AppleAudioCategoryOption" added (CI02) (minor)
├── Interface "AppleAudioMode" added (CI02) (minor)
├── Interface "ValueOrAbsent" added (CI02) (minor)
├── Interface "AndroidAudioSessionConfiguration" added (CI02) (minor)
├── Interface "AndroidAudioMode" added (CI02) (minor)
├── Interface "AndroidAudioFocusMode" added (CI02) (minor)
├── Interface "AndroidAudioStreamType" added (CI02) (minor)
├── Interface "AndroidAudioAttributesUsageType" added (CI02) (minor)
├── Interface "AndroidAudioAttributesContentType" added (CI02) (minor)
├── Interface "AudioEngineState" added (CI02) (minor)
├── Interface "AudioManager" added (CI02) (minor)
├── Interface "AudioSessionManagementMode" added (CI02) (minor)
├── Interface "AudioProcessingState" added (CI02) (minor)
├── Interface "AudioProcessingComponentState" added (CI02) (minor)
├── Interface "AudioProcessingComponentRequest" added (CI02) (minor)
├── Interface "AudioProcessingImplementation" added (CI02) (minor)
├── Interface "AudioProcessingException" added (CI02) (minor)
├── Interface "AudioProcessingFailureReason" added (CI02) (minor)
├── Interface "AdaptiveStreamPixelDensity" added (CI02) (minor)
├── Function "lkPlatformSupportsExplicitAudioRecordingStart" added (CE11) (minor)
├── Package dependency "flutter_webrtc" version changed from "1.4.0" to "1.5.2" (CD03) (minor)
├─┬ Class AudioCaptureOptions
│ ├── Method "toMap" added (CE11) (minor)
│ ├── Field "processing" added (CF02) (minor)
│ ├── Field "echoCancellationMode" added (CF02) (minor)
│ ├── Field "noiseSuppressionMode" added (CF02) (minor)
│ ├── Field "autoGainControlMode" added (CF02) (minor)
│ ├── Field "highPassFilterMode" added (CF02) (minor)
│ ├── Super Type "AudioProcessingOptions" added (CI04) (minor)
│ ├─┬ Method copyWith
│ │ ├── Parameter "echoCancellationMode" added (CE02) (minor)
│ │ ├── Parameter "noiseSuppressionMode" added (CE02) (minor)
│ │ ├── Parameter "autoGainControlMode" added (CE02) (minor)
│ │ ├── Parameter "highPassFilterMode" added (CE02) (minor)
│ │ ├── Parameter "processing" added (CE02) (minor)
│ │ ├── Parameter "voiceIsolation" added (CE02) (minor)
│ │ ├── Parameter "stopAudioCaptureOnMute" added (CE02) (minor)
│ │ └── Parameter "processor" added (CE02) (minor)
│ └─┬ Constructor new
│   ├── Parameter "echoCancellationMode" added (CE02) (minor)
│   ├── Parameter "noiseSuppressionMode" added (CE02) (minor)
│   ├── Parameter "autoGainControlMode" added (CE02) (minor)
│   └── Parameter "highPassFilterMode" added (CE02) (minor)
├─┬ Class lk_models.TrackInfo
│ ├── Field "packetTrailerFeatures" added (CF02) (minor)
│ └─┬ Constructor new
│   └── Parameter "packetTrailerFeatures" added (CE02) (minor)
├─┬ Class LocalAudioTrack
│ └── Method "setAudioProcessingOptions" added (CE11) (minor)
├─┬ Class RpcRequest
│ ├── Method "hasCompressedPayload" added (CE11) (minor)
│ ├── Method "clearCompressedPayload" added (CE11) (minor)
│ ├── Field "compressedPayload" added (CF02) (minor)
│ └─┬ Constructor new
│   └── Parameter "compressedPayload" added (CE02) (minor)
├─┬ Class RpcResponse
│ ├── Method "hasCompressedPayload" added (CE11) (minor)
│ ├── Method "clearCompressedPayload" added (CE11) (minor)
│ ├── Field "compressedPayload" added (CF02) (minor)
│ └─┬ Constructor new
│   └── Parameter "compressedPayload" added (CE02) (minor)
├─┬ Class RpcResponse_Value
│ └── Field "compressedPayload" added (CF02) (minor)
├─┬ Class RoomHardwareManagementMethods
│ └─┬ Method setSpeakerOn
│   └── Deprecated Flag changed. false -> true (CE13) (minor)
├─┬ Class Hardware
│ ├─┬ Method setAutomaticConfigurationEnabled
│ │ └── Deprecated Flag changed. false -> true (CE13) (minor)
│ └─┬ Method setSpeakerphoneOn
│   └── Deprecated Flag changed. false -> true (CE13) (minor)
├─┬ Class LiveKitClient
│ └─┬ Method initialize
│   └── Parameter "initialAudioSessionOptions" added (CE02) (minor)
├─┬ Class TokenRequestOptions
│ ├── Field "agentDeployment" added (CF02) (minor)
│ └─┬ Constructor new
│   └── Parameter "agentDeployment" added (CE02) (minor)
├─┬ Class RoomAgentDispatch
│ ├── Field "deployment" added (CF02) (minor)
│ └─┬ Constructor new
│   └── Parameter "deployment" added (CE02) (minor)
├─┬ Class lk_models.ParticipantPermission
│ ├── Method "hasCanManageAgentSession" added (CE11) (minor)
│ ├── Method "clearCanManageAgentSession" added (CE11) (minor)
│ ├── Field "canManageAgentSession" added (CF02) (minor)
│ └─┬ Constructor new
│   └── Parameter "canManageAgentSession" added (CE02) (minor)
└─┬ Class VideoTrackRenderer
  ├── Field "adaptiveStreamPixelDensity" added (CF02) (minor)
  └─┬ Constructor new
    └── Parameter "adaptiveStreamPixelDensity" added (CE02) (minor)
To learn more about the detected changes visit: https://github.com/bmw-tech/dart_apitool/blob/main/readme/change_codes.md
Version Check
New Version is too low!

Old version: "2.7.0"
New version: "2.8.0"
Needed version: "3.0.0"

Got "2.8.0" expected >= "3.0.0" (breaking changes)

If this is intentional, please add a changeset with major level in .changes/:

major type="changed" "Description of breaking change"

…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>
@td-famedly

Copy link
Copy Markdown
Member Author

maybe we just go back to upstream

@td-famedly td-famedly closed this Jun 30, 2026
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.

7 participants