feat(desktop): auto-grant getUserMedia on Linux + Windows #127

Merged
nrupard merged 1 commit from feat/lc-129-getusermedia-permission-hooks into main 2026-05-18 16:27:55 +02:00
Owner

Summary

Closes LC-129. Wires media-stream permission handlers into the underlying webview so WebRTC voice / video calls work without per-platform user intervention. Covers LC-129's Linux + Windows scope; Apple + mobile slices live in LC-134 / LC-135 / LC-136 under the LC-133 deferred tracker.

Behaviour

Linux (WebKit2GTK) silently denies getUserMedia unless the host handles the permission-request signal; without this PR the camera / mic prompt never reaches the OS and a call attempt fails silently. Now the WebKit2GTK webview's connect_permission_request handler downcasts UserMediaPermissionRequest and calls request.allow(), so the OS-level prompt surfaces once and the granted permission is remembered across launches via WebKit2GTK's normal per-origin cache.

Windows (WebView2) cancels PermissionRequested by default. The new handler wires off the controller returned by wry's PlatformWebview::controller() and sets state to COREWEBVIEW2_PERMISSION_STATE_ALLOW for CAMERA and MICROPHONE. WebView2 persists the allow decision in its user data folder.

Unconditional grant is acceptable here: the webview never navigates off LETS_CHAT_SERVER_URL (config.rs + the set_server_url IPC command enforce this), and a compromised configured server can already exfiltrate everything via the IPC bridge, so denying inside the binary would not add a meaningful capability boundary.

Dependency notes

webview2-com = "0.38" and windows = "0.61" are pinned to align with the transitive versions wry pulls in. An earlier attempt with webview2-com = "0.33" blew up with the two-version webview2-com-sys cargo error (the Param<ICoreWebView2PermissionRequestedEventHandler> trait bound resolves against the wrong version).

webkit2gtk = "2" matches the libwebkit2gtk-4.1 ABI that wry links against.

Test plan

  • ./dev/cargo-desktop check -p lets-chat-desktop (Linux compile, dev profile)
  • just build-desktop-windows (cross-compile to x86_64-pc-windows-gnu, release profile)
  • just check (workspace fmt + clippy across standalone and saas)
  • Manual: open a 1:1 WebRTC voice call in a built Linux desktop binary; confirm exactly ONE OS-level mic prompt surfaces and is remembered across relaunch.
  • Manual: same on a Windows install.
## Summary Closes [LC-129](https://niceguyit.myjetbrains.com/youtrack/issue/LC-129). Wires media-stream permission handlers into the underlying webview so WebRTC voice / video calls work without per-platform user intervention. Covers LC-129's Linux + Windows scope; Apple + mobile slices live in LC-134 / LC-135 / LC-136 under the LC-133 deferred tracker. ## Behaviour Linux (WebKit2GTK) silently denies `getUserMedia` unless the host handles the `permission-request` signal; without this PR the camera / mic prompt never reaches the OS and a call attempt fails silently. Now the WebKit2GTK webview's `connect_permission_request` handler downcasts `UserMediaPermissionRequest` and calls `request.allow()`, so the OS-level prompt surfaces once and the granted permission is remembered across launches via WebKit2GTK's normal per-origin cache. Windows (WebView2) cancels `PermissionRequested` by default. The new handler wires off the controller returned by wry's `PlatformWebview::controller()` and sets state to `COREWEBVIEW2_PERMISSION_STATE_ALLOW` for `CAMERA` and `MICROPHONE`. WebView2 persists the allow decision in its user data folder. Unconditional grant is acceptable here: the webview never navigates off `LETS_CHAT_SERVER_URL` (config.rs + the `set_server_url` IPC command enforce this), and a compromised configured server can already exfiltrate everything via the IPC bridge, so denying inside the binary would not add a meaningful capability boundary. ## Dependency notes `webview2-com = "0.38"` and `windows = "0.61"` are pinned to align with the transitive versions wry pulls in. An earlier attempt with `webview2-com = "0.33"` blew up with the two-version `webview2-com-sys` cargo error (the `Param<ICoreWebView2PermissionRequestedEventHandler>` trait bound resolves against the wrong version). `webkit2gtk = "2"` matches the libwebkit2gtk-4.1 ABI that wry links against. ## Test plan - [x] `./dev/cargo-desktop check -p lets-chat-desktop` (Linux compile, dev profile) - [x] `just build-desktop-windows` (cross-compile to `x86_64-pc-windows-gnu`, release profile) - [x] `just check` (workspace fmt + clippy across standalone and saas) - [ ] Manual: open a 1:1 WebRTC voice call in a built Linux desktop binary; confirm exactly ONE OS-level mic prompt surfaces and is remembered across relaunch. - [ ] Manual: same on a Windows install.
feat(desktop): auto-grant getUserMedia on Linux + Windows
All checks were successful
Check / clippy + fmt + tests (pull_request) Successful in 56s
231f106bd1
Wires media-stream permission handlers into the underlying webview so
WebRTC voice / video calls work without per-platform user intervention,
covering LC-129's Linux + Windows scope (Apple + mobile slices live in
LC-134 / LC-135 / LC-136 under the LC-133 deferred tracker).

Linux (WebKit2GTK) silently denies `getUserMedia` unless the host
handles the `permission-request` signal; Windows (WebView2) cancels
PermissionRequested by default. Both paths now allow camera / mic
requests originating from the configured server URL. The webview never
navigates off `LETS_CHAT_SERVER_URL` and a compromised server can
already exfiltrate via the IPC bridge, so unconditional allow inside
the binary is no weaker than the surrounding trust model.

webview2-com / windows crate versions pinned to align with the
transitive deps wry pulls in (two-version dependency-graph error
surfaces immediately otherwise).
nrupard deleted branch feat/lc-129-getusermedia-permission-hooks 2026-05-18 16:27:56 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
psa-systems/lets-chat!127
No description provided.