Skip to content

Commit e281932

Browse files
committed
add: camera permission check/request
1 parent 06ce57b commit e281932

File tree

4 files changed

+149
-50
lines changed

4 files changed

+149
-50
lines changed

android/src/main/java/com/zxcpoiu/incallmanager/InCallManagerModule.java

Lines changed: 85 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ public class InCallManagerModule extends ReactContextBaseJavaModule implements L
5353
private static final String TAG = REACT_NATIVE_MODULE_NAME;
5454
private static ReactApplicationContext reactContext;
5555
private static SparseArray<Promise> mRequestPermissionCodePromises;
56+
private static SparseArray<String> mRequestPermissionCodeTargetPermission;
5657

5758
// --- Screen Manager
5859
private PowerManager mPowerManager;
@@ -99,6 +100,7 @@ public class InCallManagerModule extends ReactContextBaseJavaModule implements L
99100
private MyPlayerInterface mBusytone;
100101
private String media = "audio";
101102
private static String recordPermission = "unknow";
103+
private static String cameraPermission = "unknow";
102104

103105
interface MyPlayerInterface {
104106
public boolean isPlaying();
@@ -130,6 +132,7 @@ public InCallManagerModule(ReactApplicationContext _reactContext) {
130132
audioUriMap.put("bundleRingbackUri", bundleRingbackUri);
131133
audioUriMap.put("bundleBusytoneUri", bundleBusytoneUri);
132134
mRequestPermissionCodePromises = new SparseArray<Promise>();
135+
mRequestPermissionCodeTargetPermission = new SparseArray<String>();
133136
Log.d(TAG, "InCallManager initialized");
134137
}
135138

@@ -1337,50 +1340,87 @@ public void checkRecordPermission(Promise promise) {
13371340
}
13381341
}
13391342

1340-
public void _checkRecordPermission() {
1341-
String _recordPermission = "unknow";
1342-
if (ContextCompat.checkSelfPermission(reactContext, permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED) {
1343-
_recordPermission = "granted";
1343+
@ReactMethod
1344+
public void checkCameraPermission(Promise promise) {
1345+
Log.d(TAG, "RNInCallManager.checkCameraPermission(): enter");
1346+
_checkCameraPermission();
1347+
if (cameraPermission.equals("unknow")) {
1348+
Log.d(TAG, "RNInCallManager.checkCameraPermission(): failed");
1349+
promise.reject(new Exception("checkCameraPermission failed"));
13441350
} else {
1345-
_recordPermission = "denied";
1351+
promise.resolve(cameraPermission);
13461352
}
1347-
recordPermission = _recordPermission;
1353+
}
1354+
1355+
private void _checkRecordPermission() {
1356+
recordPermission = _checkPermission(permission.RECORD_AUDIO);
13481357
Log.d(TAG, String.format("RNInCallManager.checkRecordPermission(): recordPermission=%s", recordPermission));
13491358
}
13501359

1360+
private void _checkCameraPermission() {
1361+
cameraPermission = _checkPermission(permission.CAMERA);
1362+
Log.d(TAG, String.format("RNInCallManager.checkCameraPermission(): cameraPermission=%s", cameraPermission));
1363+
}
1364+
1365+
private String _checkPermission(String targetPermission) {
1366+
if (ContextCompat.checkSelfPermission(reactContext, targetPermission) == PackageManager.PERMISSION_GRANTED) {
1367+
return "granted";
1368+
} else {
1369+
return "denied";
1370+
}
1371+
}
1372+
13511373
@ReactMethod
13521374
public void requestRecordPermission(Promise promise) {
13531375
Log.d(TAG, "RNInCallManager.requestRecordPermission(): enter");
13541376
_checkRecordPermission();
13551377
if (!recordPermission.equals("granted")) {
1356-
Activity currentActivity = getCurrentActivity();
1357-
if (currentActivity == null) {
1358-
Log.d(TAG, "RNInCallManager.requestRecordPermission(): ReactContext doesn't hava any Activity attached.");
1359-
promise.reject(new Exception("requestRecordPermission(): currentActivity is not attached"));
1360-
}
1361-
int requestPermissionCode = getRandomInteger(1, 99999999);
1362-
while (mRequestPermissionCodePromises.get(requestPermissionCode, null) != null) {
1363-
requestPermissionCode = getRandomInteger(1, 99999999);
1364-
}
1365-
mRequestPermissionCodePromises.put(requestPermissionCode, promise);
1366-
/*
1367-
if (ActivityCompat.shouldShowRequestPermissionRationale(currentActivity, permission.RECORD_AUDIO)) {
1368-
showMessageOKCancel("You need to allow access to microphone for making call", new DialogInterface.OnClickListener() {
1369-
@Override
1370-
public void onClick(DialogInterface dialog, int which) {
1371-
ActivityCompat.requestPermissions(currentActivity, new String[] {permission.RECORD_AUDIO}, requestPermissionCode);
1372-
}
1373-
});
1374-
return;
1375-
}
1376-
*/
1377-
ActivityCompat.requestPermissions(currentActivity, new String[] {permission.RECORD_AUDIO}, requestPermissionCode);
1378+
_requestPermission(permission.RECORD_AUDIO, promise);
13781379
} else {
13791380
// --- already granted
13801381
promise.resolve(recordPermission);
13811382
}
13821383
}
13831384

1385+
@ReactMethod
1386+
public void requestCameraPermission(Promise promise) {
1387+
Log.d(TAG, "RNInCallManager.requestCameraPermission(): enter");
1388+
_checkCameraPermission();
1389+
if (!cameraPermission.equals("granted")) {
1390+
_requestPermission(permission.CAMERA, promise);
1391+
} else {
1392+
// --- already granted
1393+
promise.resolve(cameraPermission);
1394+
}
1395+
}
1396+
1397+
private void _requestPermission(String targetPermission, Promise promise) {
1398+
Activity currentActivity = getCurrentActivity();
1399+
if (currentActivity == null) {
1400+
Log.d(TAG, String.format("RNInCallManager._requestPermission(): ReactContext doesn't hava any Activity attached when requesting %s", targetPermission));
1401+
promise.reject(new Exception("_requestPermission(): currentActivity is not attached"));
1402+
return;
1403+
}
1404+
int requestPermissionCode = getRandomInteger(1, 99999999);
1405+
while (mRequestPermissionCodePromises.get(requestPermissionCode, null) != null) {
1406+
requestPermissionCode = getRandomInteger(1, 99999999);
1407+
}
1408+
mRequestPermissionCodePromises.put(requestPermissionCode, promise);
1409+
mRequestPermissionCodeTargetPermission.put(requestPermissionCode, targetPermission);
1410+
/*
1411+
if (ActivityCompat.shouldShowRequestPermissionRationale(currentActivity, permission.RECORD_AUDIO)) {
1412+
showMessageOKCancel("You need to allow access to microphone for making call", new DialogInterface.OnClickListener() {
1413+
@Override
1414+
public void onClick(DialogInterface dialog, int which) {
1415+
ActivityCompat.requestPermissions(currentActivity, new String[] {permission.RECORD_AUDIO}, requestPermissionCode);
1416+
}
1417+
});
1418+
return;
1419+
}
1420+
*/
1421+
ActivityCompat.requestPermissions(currentActivity, new String[] {targetPermission}, requestPermissionCode);
1422+
}
1423+
13841424
private static int getRandomInteger(int min, int max) {
13851425
if (min >= max) {
13861426
throw new IllegalArgumentException("max must be greater than min");
@@ -1392,29 +1432,36 @@ private static int getRandomInteger(int min, int max) {
13921432
protected static void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
13931433
Log.d(TAG, "RNInCallManager.onRequestPermissionsResult(): enter");
13941434
Promise promise = mRequestPermissionCodePromises.get(requestCode, null);
1435+
String targetPermission = mRequestPermissionCodeTargetPermission.get(requestCode, null);
13951436
mRequestPermissionCodePromises.delete(requestCode);
1396-
if (promise != null) {
1437+
mRequestPermissionCodeTargetPermission.delete(requestCode);
1438+
if (promise != null && targetPermission != null) {
13971439

13981440
Map<String, Integer> permissionResultMap = new HashMap<String, Integer>();
13991441

14001442
for (int i = 0; i < permissions.length; i++) {
14011443
permissionResultMap.put(permissions[i], grantResults[i]);
14021444
}
14031445

1404-
if (!permissionResultMap.containsKey(permission.RECORD_AUDIO)) {
1405-
Log.wtf(TAG, "RNInCallManager.onRequestPermissionsResult(): requested permission RECORD_AUDIO but did not appear");
1406-
promise.reject("RECORD_AUDIO_PERMISSION_NOT_FOUND", "requested permission RECORD_AUDIO but did not appear");
1446+
if (!permissionResultMap.containsKey(targetPermission)) {
1447+
Log.wtf(TAG, String.format("RNInCallManager.onRequestPermissionsResult(): requested permission %s but did not appear", targetPermission));
1448+
promise.reject(String.format("%s_PERMISSION_NOT_FOUND", targetPermission), String.format("requested permission %s but did not appear", targetPermission));
14071449
return;
14081450
}
14091451

1410-
String _recordPermission = "unknow";
1411-
if (permissionResultMap.get(permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED) {
1412-
_recordPermission = "granted";
1452+
String _requestPermissionResult = "unknow";
1453+
if (permissionResultMap.get(targetPermission) == PackageManager.PERMISSION_GRANTED) {
1454+
_requestPermissionResult = "granted";
14131455
} else {
1414-
_recordPermission = "denied";
1456+
_requestPermissionResult = "denied";
14151457
}
1416-
recordPermission = _recordPermission;
1417-
promise.resolve(recordPermission);
1458+
1459+
if (targetPermission.equals(permission.RECORD_AUDIO)) {
1460+
recordPermission = _requestPermissionResult;
1461+
} else if (targetPermission.equals(permission.CAMERA)) {
1462+
cameraPermission = _requestPermissionResult;
1463+
}
1464+
promise.resolve(_requestPermissionResult);
14181465
} else {
14191466
//super.onRequestPermissionsResult(requestCode, permissions, grantResults);
14201467
Log.wtf(TAG, "RNInCallManager.onRequestPermissionsResult(): request code not found");

index.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,13 @@ var _InCallManager = require('react-native').NativeModules.InCallManager;
44
class InCallManager {
55
constructor() {
66
this.recordPermission = 'unknow';
7+
this.caeraPermission = 'unknow';
78
this.checkRecordPermission = this.checkRecordPermission.bind(this);
89
this.requestRecordPermission = this.requestRecordPermission.bind(this);
10+
this.checkCameraPermission = this.checkCameraPermission.bind(this);
11+
this.requestCameraPermission = this.requestCameraPermission.bind(this);
912
this.checkRecordPermission();
13+
this.checkCameraPermission();
1014
}
1115

1216
start(setup) {
@@ -77,6 +81,20 @@ class InCallManager {
7781
this.recordPermission = result;
7882
return result;
7983
}
84+
85+
async checkCameraPermission() {
86+
// --- on android which api < 23, it will always be "granted"
87+
let result = await _InCallManager.checkCameraPermission();
88+
this.cameraPermission = result;
89+
return result;
90+
}
91+
92+
async requestCameraPermission() {
93+
// --- on android which api < 23, it will always be "granted"
94+
let result = await _InCallManager.requestCameraPermission();
95+
this.cameraPermission = result;
96+
return result;
97+
}
8098
}
8199

82100
export default new InCallManager();

ios/RNInCallManager/RNInCallManager.swift

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ class RNInCallManager: NSObject, AVAudioPlayerDelegate {
5353
let automatic: Bool = true
5454
var forceSpeakerOn: Int = 0 //UInt8?
5555
var recordPermission: String!
56+
var cameraPermission: String!
5657
var media: String = "audio"
5758

5859
//@objc func initWithBridge(_bridge: RCTBridge) {
@@ -859,18 +860,7 @@ class RNInCallManager: NSObject, AVAudioPlayerDelegate {
859860
} else {
860861
// --- target api at least iOS7+
861862
usingApi = "iOS7"
862-
switch AVCaptureDevice.authorizationStatusForMediaType(AVMediaTypeAudio) {
863-
case AVAuthorizationStatus.Authorized:
864-
recordPermission = "granted"
865-
case AVAuthorizationStatus.Denied:
866-
recordPermission = "denied"
867-
case AVAuthorizationStatus.NotDetermined:
868-
recordPermission = "undetermined"
869-
case AVAuthorizationStatus.Restricted:
870-
recordPermission = "restricted"
871-
default:
872-
recordPermission = "unknow"
873-
}
863+
recordPermission = self._checkMediaPermission(AVMediaTypeAudio)
874864
}
875865
self.recordPermission = recordPermission
876866
NSLog("RNInCallManager._checkRecordPermission(): using \(usingApi) api. recordPermission=\(self.recordPermission)")
@@ -889,6 +879,48 @@ class RNInCallManager: NSObject, AVAudioPlayerDelegate {
889879
})
890880
}
891881

882+
@objc func checkCameraPermission(resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) {
883+
self._checkCameraPermission()
884+
if self.cameraPermission != nil {
885+
resolve(self.cameraPermission)
886+
} else {
887+
reject("error_code", "error message", NSError(domain:"checkCameraPermission", code: 0, userInfo: nil))
888+
}
889+
}
890+
891+
func _checkCameraPermission() -> Void {
892+
self.cameraPermission = self._checkMediaPermission(AVMediaTypeVideo)
893+
NSLog("RNInCallManager._checkCameraPermission(): using iOS7 api. cameraPermission=\(self.cameraPermission)")
894+
}
895+
896+
@objc func requestCameraPermission(resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) {
897+
NSLog("RNInCallManager.requestCameraPermission(): waiting for user confirmation...")
898+
AVCaptureDevice.requestAccessForMediaType(AVMediaTypeVideo, completionHandler: {(granted: Bool) -> Void in
899+
if granted {
900+
self.cameraPermission = "granted"
901+
} else {
902+
self.cameraPermission = "denied"
903+
}
904+
NSLog("RNInCallManager.requestCameraPermission(): \(self.cameraPermission)")
905+
resolve(self.cameraPermission)
906+
})
907+
}
908+
909+
func _checkMediaPermission(targetMediaType: String) -> String {
910+
switch AVCaptureDevice.authorizationStatusForMediaType(targetMediaType) {
911+
case AVAuthorizationStatus.Authorized:
912+
return "granted"
913+
case AVAuthorizationStatus.Denied:
914+
return "denied"
915+
case AVAuthorizationStatus.NotDetermined:
916+
return "undetermined"
917+
case AVAuthorizationStatus.Restricted:
918+
return "restricted"
919+
default:
920+
return "unknow"
921+
}
922+
}
923+
892924
func debugApplicationState() -> Void {
893925
var appState = "unknow"
894926
switch UIApplication.sharedApplication().applicationState {

ios/RNInCallManager/RNInCallManagerBridge.m

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,7 @@ @interface RCT_EXTERN_REMAP_MODULE(InCallManager, RNInCallManager, NSObject)
2222
RCT_EXTERN_METHOD(stopRingtone)
2323
RCT_EXTERN_METHOD(checkRecordPermission:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
2424
RCT_EXTERN_METHOD(requestRecordPermission:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
25+
RCT_EXTERN_METHOD(checkCameraPermission:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
26+
RCT_EXTERN_METHOD(requestCameraPermission:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
2527

2628
@end

0 commit comments

Comments
 (0)