Skip to content

Commit 57d4c3d

Browse files
authored
fix(messaging,android): fix call race that could happen when using requestPermission (#18256)
1 parent 2db3166 commit 57d4c3d

1 file changed

Lines changed: 32 additions & 16 deletions

File tree

packages/firebase_messaging/firebase_messaging/android/src/main/java/io/flutter/plugins/firebase/messaging/FlutterFirebasePermissionManager.java

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@
1717
import java.util.ArrayList;
1818

1919
class FlutterFirebasePermissionManager implements PluginRegistry.RequestPermissionsResultListener {
20+
private static final String REQUEST_IN_PROGRESS_ERROR =
21+
"A request for permissions is already running, please wait for it to finish before doing "
22+
+ "another request.";
2023

24+
private final Object requestLock = new Object();
2125
private final int permissionCode = 240;
2226
@Nullable private RequestPermissionsSuccessCallback successCallback;
2327
private boolean requestInProgress = false;
@@ -30,15 +34,32 @@ interface RequestPermissionsSuccessCallback {
3034
@Override
3135
public boolean onRequestPermissionsResult(
3236
int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
33-
if (requestInProgress && requestCode == permissionCode && this.successCallback != null) {
37+
final RequestPermissionsSuccessCallback callback;
38+
synchronized (requestLock) {
39+
if (!requestInProgress || requestCode != permissionCode || this.successCallback == null) {
40+
return false;
41+
}
42+
43+
callback = this.successCallback;
44+
this.successCallback = null;
3445
requestInProgress = false;
35-
boolean granted =
36-
grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED;
46+
}
47+
48+
boolean granted =
49+
grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED;
50+
callback.onSuccess(granted ? 1 : 0);
51+
return true;
52+
}
53+
54+
private boolean setRequestInProgress(RequestPermissionsSuccessCallback successCallback) {
55+
synchronized (requestLock) {
56+
if (requestInProgress) {
57+
return false;
58+
}
3759

38-
this.successCallback.onSuccess(granted ? 1 : 0);
60+
requestInProgress = true;
61+
this.successCallback = successCallback;
3962
return true;
40-
} else {
41-
return false;
4263
}
4364
}
4465

@@ -47,25 +68,20 @@ public void requestPermissions(
4768
Activity activity,
4869
RequestPermissionsSuccessCallback successCallback,
4970
ErrorCallback errorCallback) {
50-
if (requestInProgress) {
51-
errorCallback.onError(
52-
"A request for permissions is already running, please wait for it to finish before doing another request.");
71+
if (activity == null) {
72+
errorCallback.onError("Unable to detect current Android Activity.");
5373
return;
5474
}
5575

56-
if (activity == null) {
57-
errorCallback.onError("Unable to detect current Android Activity.");
76+
if (!setRequestInProgress(successCallback)) {
77+
errorCallback.onError(REQUEST_IN_PROGRESS_ERROR);
5878
return;
5979
}
6080

61-
this.successCallback = successCallback;
6281
final ArrayList<String> permissions = new ArrayList<String>();
6382
permissions.add(Manifest.permission.POST_NOTIFICATIONS);
6483
final String[] requestNotificationPermission = permissions.toArray(new String[0]);
6584

66-
if (!requestInProgress) {
67-
ActivityCompat.requestPermissions(activity, requestNotificationPermission, permissionCode);
68-
requestInProgress = true;
69-
}
85+
ActivityCompat.requestPermissions(activity, requestNotificationPermission, permissionCode);
7086
}
7187
}

0 commit comments

Comments
 (0)