Skip to content

Modernize the Flutter example app - #1066

Merged
hiroshihorie merged 9 commits into
mainfrom
hiroshi/modernize-flutter-example-app
Aug 11, 2026
Merged

Modernize the Flutter example app#1066
hiroshihorie merged 9 commits into
mainfrom
hiroshi/modernize-flutter-example-app

Conversation

@hiroshihorie

Copy link
Copy Markdown
Member

No description provided.

@hiroshihorie
hiroshihorie marked this pull request as ready for review June 19, 2026 19:17
…tter-example-app

# Conflicts:
#	example/lib/pages/connect.dart
devin-ai-integration[bot]

This comment was marked as resolved.

@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 found 3 new potential issues.

View 1 additional finding in Devin Review.

Open in Devin Review

Comment on lines +313 to +315
if (!hasVideoPublication) {
userMediaTracks.add(ParticipantTrack(participant: participant));
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Participants who share their screen with the camera off disappear from the participant view

A participant tile is only added when the participant has no video publications at all (if (!hasVideoPublication) at example/lib/pages/room.dart:313-315), so someone whose only video is a screen share gets no personal tile, meaning they vanish from the participant view while sharing.
Impact: While a camera-off user shares their screen, other people can no longer see that user's tile (name, speaking indicator, avatar) in the room.

Why the screen-share-only case falls through the audio-only fallback

The loop sets hasVideoPublication = true for every video publication, including screen shares. A screen-share publication therefore suppresses the fallback that was added to show audio-only participants, and the screen-share entry itself is pushed into screenTracks rather than a user-media tile. The same pattern is duplicated for the local participant at example/lib/pages/room.dart:352-354. A fix would track camera (non-screen-share) publications separately from screen-share publications, e.g. only skip the fallback when a non-screen-share video publication was seen.

Prompt for agents
In example/lib/pages/room.dart, _sortParticipants() adds a fallback user-media tile only when a participant has zero video publications (hasVideoPublication). Because screen-share publications also set that flag, a participant whose only video publication is a screen share gets no personal tile at all (their screen share appears, but they themselves disappear from the grid). The same logic is duplicated for the local participant later in the same function. Consider tracking camera/user-media publications separately from screen-share publications so the fallback tile is added whenever there is no non-screen-share video publication.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

33CC10EB2044A3C60003C045 /* Resources */,
33CC110E2044A8840003C045 /* Bundle Framework */,
3399D490228B24CF009A79C7 /* ShellScript */,
514FABDBA3BE0B4C6B1D1F14 /* [CP] Embed Pods Frameworks */,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 macOS example app may fail to launch because the step that bundles its CocoaPods frameworks was deleted

The build step that copies the CocoaPods dynamic frameworks into the macOS example app bundle was removed from the app target ([CP] Embed Pods Frameworks deleted at example/macos/Runner.xcodeproj/project.pbxproj:192), so the app links against libraries that are no longer packaged with it.
Impact: Building and running the macOS example from the committed Xcode project can crash at launch with a missing-library error until CocoaPods regenerates the step.

Why the phase is required for this target

example/macos/Podfile declares use_frameworks!, so pods (including the WebRTC xcframework pulled in by flutter_webrtc) are built as dynamic frameworks and must be embedded by the [CP] Embed Pods Frameworks script phase. Both the phase reference in the Runner target's buildPhases and the PBXShellScriptBuildPhase definition itself were deleted, while Pods_Runner.framework remains linked in the Frameworks phase. The iOS project still contains the equivalent phase (example/ios/Runner.xcodeproj/project.pbxproj:210). Running pod install will re-add it, which is likely why the removal was not noticed, but it should be restored so the checked-in project builds standalone.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +203 to 224
url: _uriCtrl.text.trim(),
token: _tokenCtrl.text.trim(),
e2ee: _e2ee,
e2eeKey: _sharedKeyCtrl.text,
simulcast: _simulcast,
adaptiveStream: _adaptiveStream,
dynacast: _dynacast,
autoSubscribe: _autoSubscribe,
multiCodec: _multiCodec,
preferredCodec: _preferredCodec,
updatedAt: DateTime.now(),
);
if (entry.url.isEmpty && entry.token.isEmpty) return;

final next = [
entry,
..._history.where(
(item) => item.url != entry.url || item.token != entry.token,
),
].take(5).toList();

setState(() {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟨 Room access tokens and E2EE keys are persisted in plaintext connection history

The new "recent connections" feature serializes the full JWT access token and the E2EE shared key into JSON and stores it in SharedPreferences (_saveCurrentConnectionToHistory at example/lib/pages/connect.dart:203-224, written via _writeHistory at example/lib/pages/connect.dart:136-142). SharedPreferences is unencrypted on disk (plist / XML / localStorage on web), so on web builds or rooted/backed-up devices any other script or process with access to the app storage can read live room credentials and the media encryption key.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

@hiroshihorie
hiroshihorie merged commit aeeeebe into main Aug 11, 2026
15 checks passed
@hiroshihorie
hiroshihorie deleted the hiroshi/modernize-flutter-example-app branch August 11, 2026 08:21
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