Skip to content

fix(hub-client): honor serve-sim WebRTC settings - #22

Open
krystofwoldrich-agent wants to merge 1 commit into
expo:mainfrom
krystofwoldrich-agent:codex/honor-serve-sim-webrtc-settings
Open

krystofwoldrich-agent wants to merge 1 commit into
expo:mainfrom
krystofwoldrich-agent:codex/honor-serve-sim-webrtc-settings

Conversation

@krystofwoldrich-agent

Copy link
Copy Markdown
Contributor

Summary

  • preserve serve-sim advertised WebRTC codec and validated ICE/TURN configuration in the Hub iOS client
  • keep codec fallback anchored to the configured or viewer-selected codec
  • expose H.264, VP9, and VP8 controls in the Device Hub sidebar and reset the FPS sample window on stream changes
  • add patch changesets for @expo/hub-client and expo-device-hub

Testing

  • bun test in packages/@expo/hub-client (55 passed)
  • bun test in packages/expo-device-hub (68 passed)
  • turbo typecheck for @expo/hub-client and @expo/hub-components
  • bun run build:web in packages/expo-device-hub

Preserve advertised codec and ICE configuration during iOS preview resolution, keep codec fallback anchored to the requested codec, and expose viewer codec controls in the dashboard.

Co-authored-by: Krystof Woldrich <31292499+krystofwoldrich@users.noreply.github.com>
Co-authored-by: Codex <noreply@openai.com>

@krystofwoldrich-agent krystofwoldrich-agent left a comment

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.

🤖 This is an automated review. Addressing it doesn't guarantee a merge.

Verdict: REQUEST_CHANGES
Findings: 0 critical · 1 design · 2 suggestion · 1 nit

The PR reads streamSettings.codec/iceServers from serve-sim /api, adds webRtcCodec/setWebRtcCodec to DeviceClient, anchors the codec fallback to the requested codec, and adds a codec control to StreamSection. Tests and typechecks pass on the PR head (hub-client 55/55, expo-device-hub 68/68). The main concern: upstream/main is 54 commits ahead of the PR base and already contains this feature (#24, #29). git merge-tree upstream/main upstream/pr/22 reports conflicts in useIosDevice.ts (10 regions) and DeviceOptionsSection.tsx (1 region). Only ICE server validation and the FPS window reset are not on main.

Findings

  • [design] Superseded by main and does not merge cleanly — packages/@expo/hub-client/src/useIosDevice.ts:342. Main has webRtcCodec/setWebRtcCodec (types.ts:534-535), reads streamSettings codec and ICE servers (useIosDevice.ts:689-691), anchors fallback to the requested codec (useIosDevice.ts:773), and renders codec controls in StreamOptionsSection.tsx:298-305. Main's DeviceOptionsSection no longer takes stream props. Recommend closing as superseded or rebasing down to the residual deltas.
  • [suggestion] Carry over the two deltas main lacks — packages/@expo/hub-client/src/useIosDevice.ts:294 (previewIceServers runtime validation; main's iOS path trusts the JSON cast while Android validates via isIceServer) and :744 (fpsCounterRef reset; main only calls setFps(0)).
  • [suggestion] Test imports a sibling package by relative path — packages/expo-device-hub/src/dashboard/__tests__/streamSection.test.tsx:4. Use the @expo/hub-components workspace package, or move the test to packages/@expo/hub-components/src/__tests__/ which exists on main.
  • [nit] Duplicate state resets on codec change — packages/@expo/hub-client/src/useIosDevice.ts:663. selectWebRtcCodec and the effect at lines 739-746 perform the same three writes.

}

/** Convert serve-sim's middleware response into the URLs consumed by the iOS client. */
export function resolveIosPreviewConfig(

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.

[design] This PR no longer merges with upstream/main (git merge-tree reports 10 conflict regions in this file and 1 in DeviceOptionsSection.tsx), and main already implements this feature. On main, toMiddleware in this hook reads c.streamSettings.codec and c.streamSettings.iceServers into ResolvedConfig.webRtcCodec/webRtcIceServers (lines 689-691), the fallback effect calls webRtcFallbackDecision(webRtcCodec, activeWebRtcCodec, failure) (line 773), DeviceClient declares webRtcCodec: DeviceWebRtcCodec and setWebRtcCodec (types.ts:534-535, non-nullable, unlike this PR), and the codec UI lives in StreamOptionsSection.tsx:298-305. Main's DeviceOptionsSection no longer takes streamMode props, so the PR's UI wiring cannot apply. Recommend closing as superseded, or rebasing down to the two deltas main lacks (see the comment on previewIceServers).


type BrowserLocation = Pick<Location, 'host' | 'protocol'>;

function previewIceServers(value: unknown): WebRtcIceServer[] | undefined {

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.

[suggestion] This validator is one of two pieces of this PR that upstream/main does not have. Main's iOS path (useIosDevice.ts:690-691) passes c.streamSettings.iceServers through on the strength of the JSON cast alone, while the Android path validates each entry (useAndroidDevice.ts:179-180, isIceServer). The other missing piece is the fpsCounterRef reset at line 744; main's reset effect (useIosDevice.ts:848-851) only calls setFps(0). A small follow-up PR against current main with these two changes plus ios-preview-config.test.ts would be easy to review.

});
const handledWebRtcFailureRef = useRef<string | null>(null);

const selectWebRtcCodec = useCallback((codec: DeviceWebRtcCodec) => {

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.

[nit] selectWebRtcCodec clears handledWebRtcFailureRef, sets webRtcCodec, and clears webRtcHttpFallback. The effect at lines 739-746 performs the same three writes whenever requestedWebRtcCodec changes, which this callback triggers. One of the two paths is enough. That effect also dispatches dispatchAvccFallback('reset') on a WebRTC codec change, which is unrelated to AVCC.

import { expect, test } from 'bun:test';
import { renderToStaticMarkup } from 'react-dom/server';

import { StreamSection } from '../../../../@expo/hub-components/src/dashboard/StreamSection';

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.

[suggestion] This reaches into a sibling package by relative path. Every other file in expo-device-hub imports the @expo/hub-components workspace package, and packages/expo-device-hub/AGENTS.md says to import UI from @expo/hub-components. The test covers a hub-components component, so it belongs in packages/@expo/hub-components/src/__tests__/ (present on main). On main the component to test is StreamOptionsSection.

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