From 9570df10e6f332aa28078148c1ec6a044dcead71 Mon Sep 17 00:00:00 2001 From: Emmanuel Quentin Date: Thu, 18 Apr 2024 10:34:16 -0400 Subject: [PATCH 1/2] Fix crash in getAudioOutput --- ios/RNCallKeep/RNCallKeep.m | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/ios/RNCallKeep/RNCallKeep.m b/ios/RNCallKeep/RNCallKeep.m index 9569e359..786045fe 100644 --- a/ios/RNCallKeep/RNCallKeep.m +++ b/ios/RNCallKeep/RNCallKeep.m @@ -131,12 +131,12 @@ - (void)startObserving - (void)stopObserving { _hasListeners = FALSE; - + // Fix for https://github.com/react-native-webrtc/react-native-callkeep/issues/406 // We use Objective-C Key Value Coding(KVC) to sync _RTCEventEmitter_ `_listenerCount`. @try { [self setValue:@0 forKey:@"_listenerCount"]; - } + } @catch ( NSException *e ){ NSLog(@"[RNCallKeep][stopObserving] exception: %@",e); NSLog(@"[RNCallKeep][stopObserving] RNCallKeep parent class RTCEventEmitter might have a broken state."); @@ -189,7 +189,16 @@ + (void)initCallKitProvider { } + (NSString *) getAudioOutput { - return [AVAudioSession sharedInstance].currentRoute.outputs.count > 0 ? [AVAudioSession sharedInstance].currentRoute.outputs[0].portType : nil; + @try{ + NSArray* outputs = [AVAudioSession sharedInstance].currentRoute.outputs; + if(outputs != nil && outputs.count > 0){ + return outputs[0].portType; + } + } @catch(NSException* error) { + NSLog(@"getAudioOutput error :%@", [error description]); + } + + return nil; } + (void)setup:(NSDictionary *)options { @@ -554,7 +563,7 @@ + (NSMutableArray *) formatAudioInputs: (NSMutableArray *)inputs { NSMutableArray *newInputs = [NSMutableArray new]; NSString * selected = [RNCallKeep getSelectedAudioRoute]; - + NSMutableDictionary *speakerDict = [[NSMutableDictionary alloc]init]; [speakerDict setObject:@"Speaker" forKey:@"name"]; [speakerDict setObject:AVAudioSessionPortBuiltInSpeaker forKey:@"type"]; @@ -645,13 +654,13 @@ + (NSString *) getSelectedAudioRoute AVAudioSession* myAudioSession = [AVAudioSession sharedInstance]; AVAudioSessionRouteDescription *currentRoute = [myAudioSession currentRoute]; NSArray *selectedOutputs = currentRoute.outputs; - + AVAudioSessionPortDescription *selectedOutput = selectedOutputs[0]; - + if(selectedOutput && [selectedOutput.portType isEqualToString:AVAudioSessionPortBuiltInReceiver]) { return @"Phone"; } - + return [RNCallKeep getAudioInputType: selectedOutput.portType]; } @@ -909,7 +918,7 @@ - (void)configureAudioSession NSUInteger categoryOptions = AVAudioSessionCategoryOptionAllowBluetooth | AVAudioSessionCategoryOptionAllowBluetoothA2DP; NSString *mode = AVAudioSessionModeDefault; - + NSDictionary *settings = [RNCallKeep getSettings]; if (settings && settings[@"audioSession"]) { if (settings[@"audioSession"][@"categoryOptions"]) { @@ -920,7 +929,7 @@ - (void)configureAudioSession mode = settings[@"audioSession"][@"mode"]; } } - + AVAudioSession* audioSession = [AVAudioSession sharedInstance]; [audioSession setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:categoryOptions error:nil]; From 65247a72c198e06df2663051b21215119c91c8fa Mon Sep 17 00:00:00 2001 From: Emmanuel Quentin Date: Thu, 18 Apr 2024 11:49:40 -0400 Subject: [PATCH 2/2] Catch security error when trying to get phone account --- .../java/io/wazo/callkeep/VoiceConnectionService.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/android/src/main/java/io/wazo/callkeep/VoiceConnectionService.java b/android/src/main/java/io/wazo/callkeep/VoiceConnectionService.java index 78f359d3..82820222 100644 --- a/android/src/main/java/io/wazo/callkeep/VoiceConnectionService.java +++ b/android/src/main/java/io/wazo/callkeep/VoiceConnectionService.java @@ -457,7 +457,14 @@ private Connection createConnection(ConnectionRequest request) { if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { Context context = getApplicationContext(); TelecomManager telecomManager = (TelecomManager) context.getSystemService(context.TELECOM_SERVICE); - PhoneAccount phoneAccount = telecomManager.getPhoneAccount(request.getAccountHandle()); + PhoneAccount phoneAccount = null; + + try { + phoneAccount = telecomManager.getPhoneAccount(request.getAccountHandle()); + } catch (Exception e) { + Log.w(TAG, "[VoiceConnectionService] getPhoneAccount error: " + e.toString()); + return; + } //If the phone account is self managed, then this connection must also be self managed. if((phoneAccount.getCapabilities() & PhoneAccount.CAPABILITY_SELF_MANAGED) == PhoneAccount.CAPABILITY_SELF_MANAGED) {