Skip to content

Commit e25436d

Browse files
committed
fix(android): avoid overgranting mixed permission requests
1 parent b9d86ef commit e25436d

1 file changed

Lines changed: 46 additions & 29 deletions

File tree

src/android/kotlin/RustWebChromeClient.kt

Lines changed: 46 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)