@@ -93,54 +93,71 @@ class RustWebChromeClient(appActivity: WryActivity) : WebChromeClient() {
9393
9494 override fun onPermissionRequest (request : PermissionRequest ) {
9595 val requestedResources = safePermissionRequestResources(request.resources)
96- val response = onPermissionRequestNative(activity.currentWebViewId(), request.resources)
97- when (response) {
98- 0 -> { // Allow
99- if (requestedResources.isNotEmpty()) {
100- request.grant(requestedResources)
101- } else {
96+ if (requestedResources.isEmpty()) {
97+ request.deny()
98+ return
99+ }
100+
101+ val grantedResources = ArrayList <String >()
102+ val defaultResources = ArrayList <String >()
103+
104+ for (resource in requestedResources) {
105+ when (onPermissionRequestNative(activity.currentWebViewId(), arrayOf(resource))) {
106+ 0 -> grantedResources.add(resource)
107+ 1 -> {
102108 request.deny()
109+ return
103110 }
104- return
105- }
106- 1 -> { // Deny
107- request.deny()
108- return
109- }
110- 2 -> { // Default
111- // Continue with default logic
112- }
113- 3 -> { // Prompt
114- // Continue with default logic (which prompts)
111+ 2 , 3 -> defaultResources.add(resource)
115112 }
116113 }
117114
118- val isRequestPermissionRequired = Build .VERSION .SDK_INT >= Build .VERSION_CODES .M
119- val permissionList: MutableList <String > = ArrayList ()
120- if (requestedResources.contains(PermissionRequest .RESOURCE_VIDEO_CAPTURE )) {
121- permissionList.add(Manifest .permission.CAMERA )
122- }
123- if (requestedResources.contains(PermissionRequest .RESOURCE_AUDIO_CAPTURE )) {
124- permissionList.add(Manifest .permission.MODIFY_AUDIO_SETTINGS )
125- permissionList.add(Manifest .permission.RECORD_AUDIO )
115+ if (grantedResources.isNotEmpty()) {
116+ // Android PermissionRequest can only be completed once. When the handler
117+ // explicitly allows a subset and leaves the rest as default/prompt, grant
118+ // only the handled subset and let the remaining resources be denied.
119+ grantPermissionRequest(request, grantedResources.toTypedArray())
120+ return
126121 }
127- if (requestedResources.isEmpty()) {
122+
123+ grantPermissionRequest(request, defaultResources.toTypedArray())
124+ }
125+
126+ private fun grantPermissionRequest (request : PermissionRequest , resources : Array <String >) {
127+ if (resources.isEmpty()) {
128128 request.deny()
129- } else if (permissionList.isNotEmpty() && isRequestPermissionRequired) {
129+ return
130+ }
131+
132+ val isRequestPermissionRequired = Build .VERSION .SDK_INT >= Build .VERSION_CODES .M
133+ val permissionList = androidPermissionsForResources(resources)
134+ if (permissionList.isNotEmpty() && isRequestPermissionRequired) {
130135 val permissions = permissionList.toTypedArray()
131136 permissionListener = object : PermissionListener {
132137 override fun onPermissionSelect (isGranted : Boolean? ) {
133138 if (isGranted == true ) {
134- request.grant(requestedResources )
139+ request.grant(resources )
135140 } else {
136141 request.deny()
137142 }
138143 }
139144 }
140145 permissionLauncher.launch(permissions)
141146 } else {
142- request.grant(requestedResources)
147+ request.grant(resources)
148+ }
149+ }
150+
151+ private fun androidPermissionsForResources (resources : Array <String >): MutableList <String > {
152+ val permissionList: MutableList <String > = ArrayList ()
153+ if (resources.contains(PermissionRequest .RESOURCE_VIDEO_CAPTURE )) {
154+ permissionList.add(Manifest .permission.CAMERA )
155+ }
156+ if (resources.contains(PermissionRequest .RESOURCE_AUDIO_CAPTURE )) {
157+ permissionList.add(Manifest .permission.MODIFY_AUDIO_SETTINGS )
158+ permissionList.add(Manifest .permission.RECORD_AUDIO )
143159 }
160+ return permissionList
144161 }
145162
146163 private external fun onPermissionRequestNative (webviewId : String , resources : Array <String >): Int
0 commit comments