Screen-share (send): startScreenShare requests the MediaProjection grant via
startActivityForResult, then CallMedia.setScreenShareEnabled(true,
ScreenCaptureParams(data)) publishes it over the native LiveKit room.
stopScreenShare unpublishes. Both emit screenShareState so the web button
reflects reality (incl. a declined grant). LiveKit's SDK manifest already
provides the mediaProjection foreground service + FOREGROUND_SERVICE_MEDIA_
PROJECTION (merged into the app), so no manifest change is needed.
Received shared screen: implemented setTileZoom (was a no-op) — the web
captures pinch/pan under hole-punch and forwards {scale,tx,ty}; CallVideo
applies it as a renderer transform (scale about centre + translate ×density),
scale<=1 clears it. Mirrors the iOS applyZoom contract. Screen tiles already
render aspect-fit.
APK-only: the web bridge already calls these methods and received-screen
rendering is gated on ANDROID_NATIVE_VIDEO (already on) — no server/web change.
All LiveKit 2.29.2 APIs (setScreenShareEnabled, ScreenCaptureParams) verified
against source. Clarity-when-zoomed (adaptive-stream) is a follow-up if needed.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
A missing brace in a home.html inline <script> caused an app-wide login
outage (the whole block failed to parse, so boot never ran). Nothing in the
deploy path checked HTML syntax. Add tools/check-syntax.js: parses (never
runs) every inline <script> in server/public/*.html with vm and exits non-zero
on any syntax error, reporting the file + line.
Wired in two places:
- Dockerfile RUN after COPY server/ ./ — a syntax error now FAILS the build,
so it can't deploy.
- redeploy.sh pre-flight — fast local feedback before triggering the remote
build.
Verified: passes on current pages (16 blocks / 9 files); fails with the exact
location when a brace is removed.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Mirrors the iOS native-video path on Android, gated by ANDROID_NATIVE_VIDEO.
- CallVideo (new): hole-punch (transparent WebView over a black parent with a
container behind) + per-tile LiveKit TextureViewRenderer, positioned from the
web's CSS-px tile rects scaled by display density. TextureView (not Surface)
so it composites behind the transparent WebView. Local camera mirrored;
camera = aspect-fill, screen = aspect-fit; stale renderers released.
- CallMedia: setCameraEnabled / switchCamera (LocalVideoTrack.switchCamera) +
cameraTrack/screenTrack lookup (by LiveKit identity = mesh peerId) +
initRenderer. All LiveKit 2.29.2 APIs verified against source.
- NativeCallPlugin: setCamera / switchCamera / setHolePunch / syncVideoTiles get
real bodies (+ CAMERA runtime-permission prompt, video teardown on endCall).
Screen-share (MediaProjection), tile zoom and #5 transcript stay no-ops.
Web needs no change: the shared NativeCall bridge already drives these for any
meetNative call; bzNativeVideoOn() enables hole-punch + the tile poll on Android
once the flag is on. Flip ANDROID_NATIVE_VIDEO=1 after a 2b APK is installed.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Codemagic build failed at :app:checkDebugAarMetadata — "Could not find
com.github.davidliu:audioswitch". LiveKit Android 2.29.2 pulls in that
JitPack-only fork (commit-hash version), and Gradle resolves the whole
:app transitive graph against the APP module's (+ allprojects) repos, not
the native-call plugin's. The plugin-level jitpack repo was therefore
ignored. android-patch.js now injects `maven { url 'https://jitpack.io' }`
into the generated root build.gradle's allprojects{} (and settings.gradle
dependencyResolutionManagement{} if a newer template uses it). Idempotent,
build-tolerant. TECHSTACK rev 3 note updated.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
LiveKit Android 2.29.2 + audioswitch + Kotlin in the native-call plugin, the
microphone foreground service, the ANDROID_NATIVE_MEDIA flag, and minSdk 24.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Full stack: plain Node (http/https + ws, custom router, no framework),
PostgreSQL 16 (SQLite retired), vanilla-JS web SPA, Capacitor 8 mobile with
custom native-call/audio/media/share plugins, two Electron clients, LiveKit
SFU + WebRTC mesh, Web Push/FCM/APNs, Docker + Nginx Proxy Manager, Codemagic
CI. Includes a maintenance rule + changelog so it's kept current.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>