Skip to content

Add RPC tester interface to example app - #1085

Merged
hiroshihorie merged 9 commits into
mainfrom
add-rpc-tester
Jul 28, 2026
Merged

hiroshihorie merged 9 commits into
mainfrom
add-rpc-tester

Conversation

@1egoman

@1egoman 1egoman commented May 15, 2026

Copy link
Copy Markdown
Contributor

Adds a new button on the bottom control bar for the "rpc tester":

Screenshot 2026-05-15 at 11 09 19 AM

When clicked, it opens up a new panel which has two sections:

Screenshot 2026-05-15 at 11 09 04 AM

The top section allows sending RPC messages - select a destination participant, topic, and enter a payload, and click "Send". Note that there are two payload presets - "hello world" and "X" * 20000 to provide some easy to generate data to test some edge cases.

The bottom section lets you configure rpc handlers. Enter a rpc handler topic and a static response, and submit. Then when this participant receives a RPC request, the request will be responded to with the static response. This static response also has the same payload presets as the request.

Warning

This pull request was LLM generated and has only been lightly reviewed by a human. The author has tested this and confirms it works in the happy path, but no other validation has been done.

A more thorough review of this needs to occur before it could be merged.

1egoman added 2 commits May 15, 2026 11:07
This can be used to exercise sending / receiving rpc requests in the example app
Comment on lines +472 to +478
children: [
Expanded(
child: Text(
entry.topic,
style: theme.textTheme.titleSmall?.copyWith(fontWeight: FontWeight.bold, color: theme.scaffoldBackgroundColor),
),
),

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

A drive by comment: the colors in this app (besides being out of date) are fairly limited, which makes styling some of these more complicated interfaces fairly challenging.

I think I might make a follow up pull request which updates the example to use the more modern color pallete / logo, and at the same time try to add in some more color scales to make this less annoying.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I did this: #1086

@1egoman 1egoman changed the title RPC tester interface to example app Add RPC tester interface to example app May 15, 2026
The RPC tester itself landed on main through #1087, which included a
hardened copy of this branch's rpc_test_sheet.dart and the controls.dart
wiring. Resolve the add/add conflict by taking main's version, so this
branch now carries only follow-up fixes.
Register the method with the room before tracking it, so a method
already registered by another component does not leave a phantom card
whose unregister button would remove a handler the tester does not own.
Cap the per handler invocation log at 200 entries and stop notifying
listeners from in flight handlers after disposal.
…ts leave

The form field only reads initialValue when its state is created, so a
stale selection could outlive its participant and trip the framework
assert that the value must be among the items. Key the field by the
participant list and validate the selection before sending.
@hiroshihorie

Copy link
Copy Markdown
Member

Updated this branch to bring it back to life. The tester itself already landed on main through #1087, which included a hardened copy of this file, so the merge resolves to main's version and keeps the original commits in history. On top of that this PR now carries follow-up fixes to the tester: registration is ordered so a method owned by another component can't leave a phantom card, the per handler invocation log is capped, in flight handlers no longer notify after disposal, and the destination dropdown stays valid when the selected participant leaves.

@github-actions

This comment has been minimized.

@hiroshihorie hiroshihorie left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Reviewed the follow-up fixes, all good. The original tester landed via #1087.

@hiroshihorie
hiroshihorie merged commit 8b00bb4 into main Jul 28, 2026
14 of 15 checks passed
@hiroshihorie
hiroshihorie deleted the add-rpc-tester branch July 28, 2026 17:20

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Open in Devin Review

@hiroshihorie hiroshihorie mentioned this pull request Aug 3, 2026
hiroshihorie added a commit that referenced this pull request Aug 3, 2026
## What

Folds the pending changesets into the 2.10.0 release. Version propagated
by `scripts/create_version.dart`, all version checks pass, `.changes/`
emptied.

## Changelog

* Added: Swift Package Manager support for iOS and macOS. CocoaPods
remains fully supported. (#1142)
* Added: `ScreenSelectDialog.show` and
`Hardware.requestCapturePermission` so apps can start screen share
without importing flutter_webrtc (#1147)
* Fixed: Compile errors on Dart 3.13 where nullable publish options are
no longer promoted across await (#1146)
* Fixed: Omit data stream totalLength when size is unknown (#1141)
* Fixed: Harden the example RPC tester (#1085)

Minor bump driven by the SPM and screen share additions.

## Why now

Dart 3.13 (Flutter 3.47 beta, soon stable) fails to compile every
published livekit_client, so #1146 needs to ship before 3.47 lands. The
screen share helpers unblock livekit/components-flutter#52, which
removes the flutter_webrtc pin conflict that downgrades users to
livekit_client 2.6.1 (livekit/components-flutter#49).

## After merge

Tag `v2.10.0` to publish. First run of the reworked publish workflow
from #1140 (tag guard, pin-warning-only validation gate, forced
publish).

Downstream: components-flutter #52 switches to `livekit_client:
^2.10.0`, then a components release and an agent-starter-flutter bump.
hiroshihorie added a commit that referenced this pull request Sep 1, 2026
Flutter counterpart of client-sdk-swift #1085, matching its final merged
behavior. Builds on #1182.

## Why

webrtc-sdk/webrtc#265 (first shipped in `m144.7559.12`) removed the
blocking mic permission request from the AudioEngine device. The
pre-enable check is now passive: it returns
`kAudioEngineErrorInsufficientDevicePermission` (-9000) instead of
prompting, so requesting permission is the SDK's job.

flutter-webrtc still pins `144.7559.10`, so this is not load-bearing
yet. It is harmless there, since `getUserMedia` in flutter-webrtc
already prompts and the status is resolved before the device's blocking
path runs. Once flutter-webrtc bumps past `.12` and the pin here
follows, this is what keeps the current behavior.

## What Flutter already had

flutter-webrtc's `getUserMedia` calls `AVCaptureDevice
requestAccessForMediaType:` and waits for the answer, so every
livekit_client mic path (publish, `restartTrack` on unmute, pre-connect
audio) already prompted before the audio device saw the track. That part
of #1085 needs no port. #1182 already maps -9000 to
`TrackCreateException` for the direct ADM entry points
(`setEngineAvailability`, `startLocalRecording`).

## What this adds

The one behavior from #1085 that was missing: only prompt while the app
can show the alert.

- Native `ensureMicrophoneAccess` in `LiveKitPlugin.swift`: `authorized`
passes, `denied`/`restricted` fail, `notDetermined` requests access. On
iOS the request is only made while
`UIApplication.shared.applicationState == .active`. An inactive or
backgrounded app (locked screen, CallKit wake, app switcher) has the
alert deferred by the system, and awaiting it would suspend
`getUserMedia` and the `_publishRunner` behind it, blocking camera and
screen share publishes for as long as the app stays there. Failing fast
lets the next foreground attempt prompt normally. macOS can present the
prompt regardless, so it always requests. No app extension concern here,
the plugin is app-only.
- The gate is skipped while engine input availability is disabled
(`setEngineAvailability`, the CallKit flow), mirroring the same late fix
in #1085: the audio device module defers opening input entirely and runs
no permission check there, so gating would turn a working background
connect into a `deviceAccessDenied` failure. The check reads the
plugin's tracked availability value, so it also covers gating done
natively before the Flutter engine exists.
- `LocalTrack.createStream` calls it for `AudioCaptureOptions` on Apple
platforms before `getUserMedia`. That is the Flutter choke point:
`LocalAudioTrack.create()`, `restartTrack()` and
`PreConnectAudioBuffer.startRecording()` all reach it. Since the prompt
in Flutter happens at `getUserMedia` rather than at capture start, the
gate sits in front of that instead of in `startCapture` as in Swift.
- Failures surface as `TrackCreateException` through the
`deviceAccessDenied` code introduced in #1182.
- Docs for `withPreConnectAudio` and
`PreConnectAudioBuffer.startRecording` now say permission is requested
at recording start but only while the app is active, so callers running
at app launch should request it up front (matching the final #1085
wording). `Native.setEngineAvailability` documents that permission is
not requested there and must be granted before input availability is
restored.

## Testing

- `flutter analyze`, `flutter test`, `dart format
--set-exit-if-changed`, `import_sorter --exit-if-changed` clean.
- Unit tests cover `Native.ensureMicrophoneAccess` (no-op when
unimplemented, propagates `deviceAccessDenied`). The `createStream` gate
is behind `lkPlatformIsApple()` and not reachable from unit tests.
- The example app builds for iOS (device SDK) and macOS with the change,
re-verified after the rebase onto `main`. On-device run against a fresh
install (first-launch prompt) and a CallKit background wake still to do.

Refs CLT-3243, client-sdk-swift#1085
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