Skip to content

fix(mobile): load iOS device streams over HTTP on Android - #14284

Merged
juliusmarminge merged 5 commits into
pingdotgg:mainfrom
akhial:fix/mobile-ios-stream-http-origin
Oct 19, 2026
Merged

juliusmarminge merged 5 commits into
pingdotgg:mainfrom
akhial:fix/mobile-ios-stream-http-origin

Conversation

@akhial

@akhial akhial commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

Problem

On the Android app, opening an iOS simulator's device preview against a plain-http environment (LAN or Tailscale IP, the common case) ended with "Could not receive the device stream. Reconnect to try again." The same simulator streamed fine in the desktop app.

The Android WebView loaded the inline stream document under a synthetic https://localhost/ origin for every target so WebCodecs (used for Android emulator targets) has a secure context. iOS targets stream an MJPEG <img> and a ws:// input socket from the environment instead, and the https document blocks those as mixed content even with mixedContentMode="always".

Change

deviceStreamBaseUrl in apps/mobile/src/features/devices/device-stream-document.ts picks the document origin:

  • Android viewer, iOS target: the environment origin (http://host:port/), so MJPEG and input are same-origin.
  • Android viewer, Android target: https://localhost/, unchanged, for WebCodecs.
  • iOS viewer: file:///, unchanged.

Stream URLs, transport selection, and auth (wsTicket query) are unchanged. The environment origin is not a secure context over http, which is fine because iOS targets never use WebCodecs on mobile. The onShouldStartLoadWithRequest guard still compares against the exact base URL string, which works for the origin form.

Unchanged and not re-checked here: Android emulator targets on an http environment keep the https://localhost/ document with a ws:// socket. If that combination has a mixed-content problem of its own, it predates this PR.

Maintainer takeover

Taken over from @akhial, who diagnosed the mixed-content cause and verified the fix on a native Android build. Their helper and wiring are kept. The three test tables were folded into one table-driven case in the existing test file, the helper's viewer parameter is typed as PlatformOSType, and main was merged in (the WebView source object is now a plain object per the React Compiler change on main).

Verification

  • pnpm test src/features/devices/device-stream-document.test.ts in apps/mobile: 22 passed. The two Android-viewer iOS-target rows fail without the fix.
  • pnpm typecheck and pnpm vp lint src/features/devices in apps/mobile pass.
  • Two independent adversarial reviews (Claude Opus 5.5, GPT-6 Sol) on the full diff found no blockers.
  • Not re-verified in this round: native Android. The author's evidence below was captured on their head (API 36.1, WebView 134, http backend, iOS 27 simulator); the origin selection is unchanged since then.
Before After
Device stream error on Android Live iOS simulator in Android T3 Code

Native app recording: touch input and Home (by the original author)

Model: Claude Fable 5.1 (takeover), GPT-6-Astra (original). Harness: Claude Code in T3 Code.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:S 10-29 changed lines (additions + deletions). labels Sep 29, 2026
@macroscopeapp

macroscopeapp Bot commented Sep 29, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 3992b5d

Macroscope's review found this PR approvable — This focused mobile bug fix changes only the WebView origin selection needed for Android to display HTTP iOS simulator streams, while preserving existing Android-target and iOS-viewer behavior. The small helper and targeted tests make the bounded runtime impact clear.

You can add or adjust custom eligibility rules. Learn more.

@coderabbitai

coderabbitai Bot commented Sep 29, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository: pingdotgg/t3code/.coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: 15af869b-e4ce-4454-9021-ab97aca21049

📥 Commits

Reviewing files that changed from the base of the PR and between d2c9281 and 3992b5d.

📒 Files selected for processing (3)
  • apps/mobile/src/features/devices/DeviceStreamWebView.tsx
  • apps/mobile/src/features/devices/device-stream-document.test.ts
  • apps/mobile/src/features/devices/device-stream-document.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.

📝 Walkthrough

The mobile device stream now selects its WebView document base URL based on the viewer platform, target platform, and HTTP base URL. The selected URL is passed to the document view. Tests cover the platform and URL combinations.

Changes: Device stream base URL

Layer / File(s) Summary
Select and apply the document base URL
apps/mobile/src/features/devices/device-stream-document.ts, apps/mobile/src/features/devices/DeviceStreamWebView.tsx, apps/mobile/src/features/devices/device-stream-document.test.ts
deviceStreamBaseUrl returns file:/// for non-Android viewers, the HTTP base URL origin for Android viewers targeting iOS, and https://localhost/ for other Android targets. DeviceStreamWebView passes the selected URL to the document view, which uses it as the WebView baseUrl. Tests cover the platform and environment URL combinations.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Suggested reviewers: juliusmarminge

Merge Risk: ⚪ Minimal · up to 3992b

The origin change is ready to merge after normal checks; invalid environment URLs show the existing connection error rather than breaking the stream view.

Security architecture risk: 🔵 Low · up to 3992b

The change lets Android display iOS streams from HTTP environments. It does not visibly change stream destinations, credentials, or the viewer’s navigation rule, and no new attack path was established. The change still places the viewer document on the selected environment’s origin.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — The origin change is confined by the selector to Android viewers of iOS targets using the selected environment; the inspected code does not show a new service endpoint or credential source.

Trust Boundaries and Controls

  • observed — The WebView’s wildcard origin whitelist and permissive mixed-content setting remain in the rendering path, alongside a top-level navigation check against the selected base URL. For HTTP environments, that allowed base now names the environment origin rather than synthetic localhost.
  • observed — Transport credentials remain part of the existing device-hub access object and are appended to device-hub request URLs, not to the new document base URL.
Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 3 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Title check Passed The title clearly and concisely describes the main change: loading iOS device streams over HTTP on Android.
Description check Passed The description clearly covers the problem, implementation, scope, testing, observed results, and UI evidence. It does not include an explicit "Scope and approval" section or a bug/approval link, but …
Full details: Description check

Explanation

The description clearly covers the problem, implementation, scope, testing, observed results, and UI evidence. It does not include an explicit "Scope and approval" section or a bug/approval link, but the focused-fix rationale and verification details make the description mostly complete.

  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR

Comment @coderabbitai help to get the list of available commands.

@juliusmarminge

Copy link
Copy Markdown
Member

Taking over this one. I'll resolve the conflict with main, rebuild the origin selection to the smallest form, and push to this branch.

juliusmarminge and others added 4 commits October 19, 2026 01:41
…-http-origin

# Conflicts:
#	apps/mobile/src/features/devices/DeviceStreamWebView.tsx
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@juliusmarminge
juliusmarminge merged commit 2b5a879 into pingdotgg:main Oct 19, 2026
27 of 28 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:S 10-29 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants