Skip to content

Commit f24a83f

Browse files
authored
Merge pull request #14 from CoolBitX-Technology/fix/android-camera-permission-issue
🐛 [CW-26589] fix: 修復 Android 在 Bridge KYC 網頁一直跳出相機權限請求的彈窗
2 parents 1001d5c + 6d77f83 commit f24a83f

File tree

3 files changed

+62
-8
lines changed

3 files changed

+62
-8
lines changed
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package com.reactnativecommunity.webview;
2+
3+
import java.util.*;
4+
5+
public class GrantedPermissionManager {
6+
private Map<String, Set<String>> map; // key: host, value: granted permissions
7+
8+
public GrantedPermissionManager() {
9+
map = new HashMap<>();
10+
}
11+
12+
// use synchronized to make thread-safe
13+
public synchronized void add(String host, List<String> permissions) {
14+
if (host == null || host.isEmpty() || permissions == null || permissions.isEmpty()) {
15+
return;
16+
}
17+
if (!map.containsKey(host)) {
18+
map.put(host, new HashSet<>());
19+
}
20+
Set<String> grantedPermissions = map.get(host);
21+
grantedPermissions.addAll(getValidPermissions(permissions));
22+
}
23+
24+
// use synchronized to make thread-safe
25+
public synchronized boolean containsAll(String host, List<String> permissions) {
26+
if (host == null || host.isEmpty() || permissions == null || permissions.isEmpty()) {
27+
return false;
28+
}
29+
return map.containsKey(host) &&
30+
map.get(host).containsAll(getValidPermissions(permissions));
31+
}
32+
33+
private List<String> getValidPermissions(List<String> permissions) {
34+
List<String> cleaned = new ArrayList<>();
35+
if (permissions == null || permissions.isEmpty()) {
36+
return cleaned;
37+
}
38+
for (String permission : permissions) {
39+
if (permission != null && !permission.isEmpty()) {
40+
cleaned.add(permission);
41+
}
42+
}
43+
return cleaned;
44+
}
45+
}

android/src/main/java/com/reactnativecommunity/webview/RNCWebChromeClient.java

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,11 @@ public class RNCWebChromeClient extends WebChromeClient implements LifecycleEven
8989

9090
protected boolean mHasOnOpenWindowEvent = false;
9191

92+
private GrantedPermissionManager grantedPermissionManager;
93+
9294
public RNCWebChromeClient(RNCWebView webView) {
9395
this.mWebView = webView;
96+
this.grantedPermissionManager = new GrantedPermissionManager();
9497
}
9598

9699
@Override
@@ -188,12 +191,15 @@ public void onPermissionRequest(final PermissionRequest request) {
188191
}
189192
}
190193

191-
if (this.shouldShowRequestPermissionDialog(grantedPermissions)) {
192-
String alertMessage = this.getRequestPermissionAlertMessage(request, grantedPermissions);
194+
String host = this.getUrlHostSafely(request);
195+
196+
if (this.shouldShowRequestPermissionDialog(host, grantedPermissions)) {
197+
String alertMessage = this.getRequestPermissionAlertMessage(host, grantedPermissions);
193198

194199
this.showRequestPermissionDialog(
195200
alertMessage,
196201
(dialog, which) -> {
202+
grantedPermissionManager.add(host, grantedPermissions);
197203
this.grantOrRequestPermission(request, requestedAndroidPermissions);
198204
},
199205
(dialog, which) -> {
@@ -206,9 +212,13 @@ public void onPermissionRequest(final PermissionRequest request) {
206212

207213
// CW-22083: 如果網頁要求麥克風或攝影機權限,就顯示權限請求對話框。
208214
// 參數只需要傳入已經被授權的權限即可。未授權的權限會由手機系統的權限請求對話框處理。
209-
private boolean shouldShowRequestPermissionDialog(List<String> grantedPermissions) {
210-
return grantedPermissions.contains(PermissionRequest.RESOURCE_AUDIO_CAPTURE) ||
215+
private boolean shouldShowRequestPermissionDialog(String host, List<String> grantedPermissions) {
216+
boolean isAudioOrVideo = grantedPermissions.contains(PermissionRequest.RESOURCE_AUDIO_CAPTURE) ||
211217
grantedPermissions.contains(PermissionRequest.RESOURCE_VIDEO_CAPTURE);
218+
boolean hasUserSeenPermissionDialog = grantedPermissionManager.containsAll(
219+
host,
220+
grantedPermissions);
221+
return isAudioOrVideo && !hasUserSeenPermissionDialog;
212222
}
213223

214224
// 如果 requestedAndroidPermissions 為空,表示手機系統已經給予所有權限給 app。app 可以直接 grant 權限給 webview。
@@ -230,7 +240,7 @@ private void grantOrRequestPermission(PermissionRequest request, List<String> re
230240
requestPermissions(requestedAndroidPermissions);
231241
}
232242

233-
private String getDisplayHostName(PermissionRequest request) {
243+
private String getUrlHostSafely(PermissionRequest request) {
234244
try {
235245
Uri originUri = request.getOrigin();
236246
return originUri.getHost();
@@ -239,7 +249,7 @@ private String getDisplayHostName(PermissionRequest request) {
239249
}
240250
}
241251

242-
private String getRequestPermissionAlertMessage(PermissionRequest request, List<String> permissions) {
252+
private String getRequestPermissionAlertMessage(String host, List<String> permissions) {
243253
List<String> permissionNames = new ArrayList<>();
244254
for (String permission : permissions) {
245255
switch (permission) {
@@ -255,7 +265,6 @@ private String getRequestPermissionAlertMessage(PermissionRequest request, List<
255265
}
256266
}
257267

258-
String host = this.getDisplayHostName(request);
259268
String permissionNamesJoined = String.join(" and ", permissionNames);
260269

261270
return String.format("Allow " + host + " to use your " + permissionNamesJoined + "?");

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"Thibault Malbranche <[email protected]>"
1111
],
1212
"license": "MIT",
13-
"version": "13.13.4-cbx.7",
13+
"version": "13.13.4-cbx.8",
1414
"publishConfig": {
1515
"access": "public",
1616
"registry": "https://registry.npmjs.org/"

0 commit comments

Comments
 (0)