Skip to content

Commit

Permalink
handle PermissionRequests in the WebChromeClient
Browse files Browse the repository at this point in the history
  • Loading branch information
adamkobor committed Sep 4, 2024
1 parent 985beb5 commit e6761c9
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package com.multiplatform.webview.web

import android.content.Context
import android.content.pm.PackageManager
import android.content.res.Configuration
import android.graphics.Bitmap
import android.os.Build
import android.view.ViewGroup
import android.webkit.PermissionRequest
import android.webkit.WebChromeClient
import android.webkit.WebResourceError
import android.webkit.WebResourceRequest
Expand All @@ -19,6 +21,7 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.viewinterop.AndroidView
import androidx.core.content.ContextCompat
import androidx.webkit.WebSettingsCompat
import androidx.webkit.WebViewFeature
import com.multiplatform.webview.jsbridge.WebViewJsBridge
Expand Down Expand Up @@ -171,6 +174,7 @@ fun AccompanistWebView(
this.restoreState(it)
}

chromeClient.context = context
webChromeClient = chromeClient
webViewClient = client

Expand Down Expand Up @@ -389,6 +393,8 @@ open class AccompanistWebViewClient : WebViewClient() {
open class AccompanistWebChromeClient : WebChromeClient() {
open lateinit var state: WebViewState
internal set
lateinit var context: Context
internal set
private var lastLoadedUrl = ""

override fun onReceivedTitle(
Expand Down Expand Up @@ -425,4 +431,59 @@ open class AccompanistWebChromeClient : WebChromeClient() {
}
lastLoadedUrl = view.url ?: ""
}

override fun onPermissionRequest(request: PermissionRequest) {
val grantedPermissions = mutableListOf<String>()
KLogger.d { "onPermissionRequest received request for resources [${request.resources}]" }

request.resources.forEach { resource ->
var androidPermission: String? = null

when (resource) {
PermissionRequest.RESOURCE_AUDIO_CAPTURE -> {
androidPermission = android.Manifest.permission.RECORD_AUDIO
}

PermissionRequest.RESOURCE_MIDI_SYSEX -> {
// MIDI sysex is only available on Android M and above
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (state.webSettings.androidWebSettings.allowMidiSysexMessages) {
grantedPermissions.add(PermissionRequest.RESOURCE_MIDI_SYSEX)
}
}
}

PermissionRequest.RESOURCE_PROTECTED_MEDIA_ID -> {
if (state.webSettings.androidWebSettings.allowProtectedMedia) {
grantedPermissions.add(PermissionRequest.RESOURCE_PROTECTED_MEDIA_ID)
}
}

PermissionRequest.RESOURCE_VIDEO_CAPTURE -> {
androidPermission = android.Manifest.permission.CAMERA
}
}

if (androidPermission != null) {
if (ContextCompat.checkSelfPermission(context, androidPermission) == PackageManager.PERMISSION_GRANTED) {
grantedPermissions.add(resource)
KLogger.d {
"onPermissionRequest permission [$androidPermission] was already granted for resource [$resource]"
}
} else {
KLogger.w {
"onPermissionRequest didn't find already granted permission [$androidPermission] for resource [$resource]"
}
}
}
}

if (grantedPermissions.isNotEmpty()) {
request.grant(grantedPermissions.toTypedArray())
KLogger.d { "onPermissionRequest granted permissions: ${grantedPermissions.joinToString()}" }
} else {
request.deny()
KLogger.d { "onPermissionRequest denied permissions: ${request.resources}" }
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,19 @@ sealed class PlatformWebSettings {
* Whether the a user gesture is required to play media. The default is {@code true}.
*/
var mediaPlaybackRequiresUserGesture: Boolean = true,
/**
* Controls whether the `RESOURCE_PROTECTED_MEDIA_ID` permission requests should be
* automatically granted or not. Necessary to be able to play back DRM protected media
* inside the WebView.
* The default is {@code false}.
*/
var allowProtectedMedia: Boolean = false,
/**
* Controls whether the `RESOURCE_MIDI_SYSEX` permission requests should be automatically
* granted or not. The resource will allow sysex messages to be sent to or received from MIDI
* devices. Available on API level 21 and above.
*/
var allowMidiSysexMessages: Boolean = false,
/**
* The Layer Type of the WebView.
* Default is [LayerType.HARDWARE]
Expand Down

0 comments on commit e6761c9

Please sign in to comment.