CI / Build & test (Node 20) (push) Canceled after 0s
CI / Build & test (Node 24) (push) Canceled after 0s
CI / Build & test (push) Canceled after 0s
CodeQL / Analyze (javascript-typescript) (push) Canceled after 0s
Security / Secret scan (gitleaks) (push) Canceled after 0s
Security / Dependency scan (OSV-Scanner) (push) Canceled after 0s
Security / IaC/config scan (Trivy) (push) Canceled after 0s
Security / License compliance scan (Trivy) (push) Canceled after 0s
OpenSSF Scorecard / Scorecard analysis (push) Canceled after 0s
A call dropped as soon as the screen locked. The cause is not configuration: Android freezes background processes, and a frozen WebView stops running the JavaScript that holds the LiveKit connection up. The only thing the system accepts as "this app must keep running" is a foreground service, which is why the persistent notification comes with it. Two mechanisms, both needed: the service stops the process from being frozen, and a partial wake lock stops the CPU from sleeping. Either one alone still drops the call. The notification carries a hangup action. The service cannot end the call itself — only the web app knows how to leave a LiveKit room — so it notifies the plugin's listeners and the web side disconnects through the same path the in-app button uses. The web side starts the service on mount when a call is already in progress, not just on transition: the WebView can reload mid-call, and waiting for the next connect would leave that call unprotected with no visible symptom until someone locked their screen. POST_NOTIFICATIONS is requested at launch on Android 13+. Denying it does not drop calls — the service still runs — it only hides the notification. Tests cover connect/disconnect, the already-in-a-call mount, the hangup action, and that the component is inert in the browser and desktop builds. Verified by mutation that dropping the start call fails the first one. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>