feat(webview): grant pages access to the microphone - #99
Merged
Merged
Conversation
An Android WebView denies audio capture unless the host app implements
WebChromeClient.onPermissionRequest. The existing client overrides only
onConsoleMessage, so getUserMedia({audio: true}) fails with NotAllowedError
and anything built on it is blocked: SIP/WebRTC intercoms, Home Assistant's
Assist button, browser push-to-talk.
Granting the request is not enough on its own. Chromium's Android audio
backend also needs MODIFY_AUDIO_SETTINGS next to RECORD_AUDIO: without it
AudioManagerAndroid.setDevice() returns false, MakeLowLatencyInputStream
returns NULL, and the page gets NotReadableError with a single line in
logcat, [ERROR:audio_manager_android.cc(326)] Unable to select audio device!
It is a normal permission, so declaring it is the whole grant - no prompt
and no runtime request.
- MainActivity: add onPermissionRequest to the WebChromeClient. Grants
RESOURCE_AUDIO_CAPTURE when the app itself holds RECORD_AUDIO and denies
everything else; audio only, these displays have no camera.
- AndroidManifest: declare MODIFY_AUDIO_SETTINGS.
The native voice assistant is unaffected - it uses AudioRecord directly,
which needs only RECORD_AUDIO, and that is why this gap is invisible there.
Verified on a Wall Display (STARGATE, Android 7.0, WebView Chrome 119) over
https: getUserMedia returns a live 16 kHz mono track and an AnalyserNode
reads real room noise (peak 0.047, rms 0.005). Before the change the same
probe returned NotAllowedError; with the permission granted but the manifest
untouched it returned NotReadableError.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
getUserMedia({audio: true})fails in the WebView, so nothing that needs capture works:SIP/WebRTC intercoms, Home Assistant's Assist button, push-to-talk. Two separate causes,
and fixing only one of them still gives no audio.
WebChromeClientinconfigureWebView()overrides onlyonConsoleMessage, socapture requests hit the default deny and the page sees
NotAllowedError.MODIFY_AUDIO_SETTINGS. Chromium wants it next toRECORD_AUDIO: without itAudioManagerAndroid.setDevice()returns false andMakeLowLatencyInputStreamreturns NULL, so the page getsNotReadableErrorandlogcat has one line,
[ERROR:audio_manager_android.cc(326)] Unable to select audio device!. It is a normal permission, so declaring it is the whole grant.So:
onPermissionRequestgrantsRESOURCE_AUDIO_CAPTUREwhen the app itself holdsRECORD_AUDIOand denies everything else - audio only, these displays have no camera -plus the one permission line in the manifest.
Tested on a Wall Display (STARGATE, Android 7.0, WebView 119) over https:
getUserMediareturns a live 16 kHz mono track and an
AnalyserNodeon it reads real room noise, so thecapture path works and not just the permission check. Video still returns
NotFoundError,as it should. The native voice assistant is unaffected - it opens
AudioRecorddirectly,which needs only
RECORD_AUDIO, and that is why this never showed up there.