Skip to content

[loop cycle 3] feat(calls): expose minimal window.chrome so WhatsApp enables call buttons#11

Merged
karem505 merged 1 commit into
masterfrom
whatrust-loop/cycle-3-enable-calls-chrome-shim
Jun 28, 2026
Merged

[loop cycle 3] feat(calls): expose minimal window.chrome so WhatsApp enables call buttons#11
karem505 merged 1 commit into
masterfrom
whatrust-loop/cycle-3-enable-calls-chrome-shim

Conversation

@karem505

Copy link
Copy Markdown
Owner

What

Targets "calls are not supported." WhatsApp Web disables the voice/video call buttons unless it judges the environment an eligible Chrome/Edge browser. The UA and navigator.userAgentData already report Chrome 131, but the calling-eligibility check also probes window.chrome, which WebKitGTK doesn't expose — so the buttons stay greyed.

Crucially, this is a detection gate, not a capability one: it was verified that this WebKitGTK build (2.52.3) ships WebRTC (libwebrtc codec symbols + enable-webrtc present), and the app already enables it and auto-grants mic/camera (enable_webview_media in window.rs). So the engine can do calls once WhatsApp considers it eligible.

How

bridge.js section 1b adds a minimal, idempotent stand-in:

if (!window.chrome) {
  Object.defineProperty(window, "chrome", {
    configurable: true, enumerable: true, writable: true,
    value: { app: { isInstalled: false }, runtime: {} },
  });
}
  • app.isInstalled:false is exactly what a normal web page in real Chrome sees — it steers WhatsApp away from the Chrome-Apps path, not into it.
  • runtime:{} satisfies a typeof chrome.runtime probe without exposing callable extension APIs.
  • Origin-guarded, own try/catch, never clobbers a genuine window.chrome.

Verification

Gate 1 — cargo build --locked + cargo test: PASS (51 tests).

Gate 2 — real WebKitGTK engine harness (origin spoofed), two cases: PASS

  • absentwindow.chrome becomes an object with runtime + app.isInstalled===false; userAgentData (3 brands) + Notification shim intact.
  • preset ({__sentinel:"real"}) → sentinel preserved (no clobber); existing shims intact.

Gate 3 — generation-blind code review: APPROVE, severity none, no must-fix. Confirmed the no-clobber guard, descriptor flags matching real Chrome, low regression risk (minimal stub avoids triggering extension/Chrome-App code paths), isolation, and idempotency.

⚠ Human-test gate (please confirm before merging)

The call button can't be exercised headlessly — it needs a logged-in WhatsApp. Before merging, please:

  1. Build/run this branch, open a chat, and check whether the voice/video call icons are now enabled (no longer greyed).
  2. Optionally start a call to confirm mic/camera negotiate.

If the buttons are still disabled, this wasn't the (only) gate — the next lever is WebRTC codec availability (H264/VP8) in this WebKitGTK build, tracked as backlog C2. Either way this change is safe and reversible (it only adds a Chrome marker).


🤖 PR-ONLY — do not auto-merge. Releasing whatRust is manual via a v* tag; this loop never merges, bumps the version, or tags a release. Opened by the whatrust-fix-loop (cycle 3/6).

…buttons

WhatsApp Web disables the voice/video call buttons unless it considers the environment
an eligible Chrome/Edge browser. The UA and navigator.userAgentData already report
Chrome 131, but the calling-eligibility check also probes for `window.chrome`, which
WebKitGTK does not expose — so the call buttons stay greyed even though this WebKitGTK
build (2.52) ships WebRTC and the app already enables it + auto-grants mic/camera.

Add a minimal, idempotent `window.chrome = { app:{isInstalled:false}, runtime:{} }`
stand-in (section 1b in bridge.js), matching what a real Chrome minimally exposes. It is
origin-guarded, wrapped in its own try/catch, and never clobbers a genuine window.chrome.

Verified in a real WebKitGTK engine (origin spoofed to web.whatsapp.com): window.chrome
becomes an object with runtime + app.isInstalled===false when absent; a pre-existing
window.chrome is preserved; the userAgentData and Notification shims are unaffected.

NOTE: whether the call button actually un-greys can only be confirmed on a logged-in
WhatsApp — see the PR's human-test gate. If it is still disabled, the next lever is
WebRTC codec availability (H264/VP8) in this WebKitGTK build (backlog C2).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016o9cWBaPy4zU4BAurUVoTp
karem505 added a commit that referenced this pull request Jun 28, 2026
Bundles six loop-shipped fixes:
- perf(dnd): stream dropped files as base64 to cut peak memory on large videos (#9)
- fix(notifications): forward service-worker showNotification to the native toast (#10)
- feat(calls): expose a minimal window.chrome so WhatsApp enables call buttons (#11)
- fix(notifications): de-duplicate burst-repeated native toasts (#12)
- fix(dnd): route AVIF/HEIF photos as photos; broaden MIME labels (#13)
- fix(calls/capability): return a complete Chrome high-entropy client-hints set (#14)
Plus integration: SW notifications share the dedup window; base64_encode is test-only now.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016o9cWBaPy4zU4BAurUVoTp
@karem505 karem505 merged commit d8c6290 into master Jun 28, 2026
6 checks passed
@karem505 karem505 deleted the whatrust-loop/cycle-3-enable-calls-chrome-shim branch June 28, 2026 01:38
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