464027401@qq.com
2021-09-27 b469805b2d0c9b23ca020cf9356ff137205f856c
HDLLinPhoneSDK(OC)/HDLLinPhoneSDK/HDLLinphoneProviderDelegate.m
@@ -35,10 +35,10 @@
   self.pendingCall = NULL;
   self.pendingAddr = NULL;
   self.pendingCallVideo = FALSE;
   CXCallController *callController = [[CXCallController alloc] initWithQueue:dispatch_get_main_queue()];
   [callController.callObserver setDelegate:self queue:dispatch_get_main_queue()];
   self.controller = callController;
   self.callKitCalls = 0;
//   CXCallController *callController = [[CXCallController alloc] initWithQueue:dispatch_get_main_queue()];
//   [callController.callObserver setDelegate:self queue:dispatch_get_main_queue()];
//   self.controller = callController;
   self.callKCalls = 0;
   if (!self) {
      NSLog(@"ProviderDelegate not initialized...");
@@ -47,21 +47,21 @@
}
- (void)config {
   CXProviderConfiguration *config = [[CXProviderConfiguration alloc]
      initWithLocalizedName:[NSBundle.mainBundle objectForInfoDictionaryKey:@"CFBundleDisplayName"]];
   config.ringtoneSound = @"notes_of_the_optimistic.caf";
   config.supportsVideo = TRUE;
   config.iconTemplateImageData = UIImagePNGRepresentation([UIImage imageNamed:@"callkit_logo"]);
   NSArray *ar = @[ [NSNumber numberWithInt:(int)CXHandleTypeGeneric] ];
   NSSet *handleTypes = [[NSSet alloc] initWithArray:ar];
   [config setSupportedHandleTypes:handleTypes];
   [config setMaximumCallGroups:2];
   [config setMaximumCallsPerCallGroup:1];
   //not show app's calls in tel's history
   //config.includesCallsInRecents = NO;
   self.provider = [[CXProvider alloc] initWithConfiguration:config];
   [self.provider setDelegate:self queue:dispatch_get_main_queue()];
//   CXProviderConfiguration *config = [[CXProviderConfiguration alloc]
//      initWithLocalizedName:[NSBundle.mainBundle objectForInfoDictionaryKey:@"CFBundleDisplayName"]];
//   config.ringtoneSound = @"notes_of_the_optimistic.caf";
//   config.supportsVideo = TRUE;
//   config.iconTemplateImageData = UIImagePNGRepresentation([UIImage imageNamed:@"callkit_logo"]);
//
//   NSArray *ar = @[ [NSNumber numberWithInt:(int)CXHandleTypeGeneric] ];
//   NSSet *handleTypes = [[NSSet alloc] initWithArray:ar];
//   [config setSupportedHandleTypes:handleTypes];
//   [config setMaximumCallGroups:2];
//   [config setMaximumCallsPerCallGroup:1];
//   //not show app's calls in tel's history
//   //config.includesCallsInRecents = NO;
//   self.provider = [[CXProvider alloc] initWithConfiguration:config];
//   [self.provider setDelegate:self queue:dispatch_get_main_queue()];
}
- (void)configAudioSession:(AVAudioSession *)audioSession {
@@ -87,32 +87,32 @@
   }
}
- (void)reportIncomingCall:(LinphoneCall *) call withUUID:(NSUUID *)uuid handle:(NSString *)handle video:(BOOL)video; {
   // Create update to describe the incoming call and caller
   CXCallUpdate *update = [[CXCallUpdate alloc] init];
   update.remoteHandle = [[CXHandle alloc] initWithType:CXHandleTypeGeneric value:handle];
   update.supportsDTMF = TRUE;
   update.supportsHolding = TRUE;
   update.supportsGrouping = TRUE;
   update.supportsUngrouping = TRUE;
   update.hasVideo = _pendingCallVideo = video;
   // Report incoming call to system
//    LOGD(@"CallKit: report new incoming call with call-id: [%@] and UUID: [%@]", [_calls objectForKey:uuid], uuid);
   [self.provider reportNewIncomingCallWithUUID:uuid
                                update:update
                             completion:^(NSError *error) {
                                if (error) {
//                                   LOGE(@"CallKit: cannot complete incoming call with call-id: [%@] and UUID: [%@] from [%@] caused by [%@]",
//                                                   [_calls objectForKey:uuid], uuid, handle, [error localizedDescription]);
                                   if ([error code] == CXErrorCodeIncomingCallErrorFilteredByDoNotDisturb ||
                                      [error code] == CXErrorCodeIncomingCallErrorFilteredByBlockList)
                                      linphone_call_decline(call,LinphoneReasonBusy); /*to give a chance for other devices to answer*/
                                   else
                                      linphone_call_decline(call,LinphoneReasonUnknown);
                                }
                             }];
}
//- (void)reportIncomingCall:(LinphoneCall *) call withUUID:(NSUUID *)uuid handle:(NSString *)handle video:(BOOL)video; {
//   // Create update to describe the incoming call and caller
//   CXCallUpdate *update = [[CXCallUpdate alloc] init];
//   update.remoteHandle = [[CXHandle alloc] initWithType:CXHandleTypeGeneric value:handle];
//   update.supportsDTMF = TRUE;
//   update.supportsHolding = TRUE;
//   update.supportsGrouping = TRUE;
//   update.supportsUngrouping = TRUE;
//   update.hasVideo = _pendingCallVideo = video;
//
//   // Report incoming call to system
////    LOGD(@"CallKit: report new incoming call with call-id: [%@] and UUID: [%@]", [_calls objectForKey:uuid], uuid);
//   [self.provider reportNewIncomingCallWithUUID:uuid
//                                update:update
//                             completion:^(NSError *error) {
//                                if (error) {
////                                   LOGE(@"CallKit: cannot complete incoming call with call-id: [%@] and UUID: [%@] from [%@] caused by [%@]",
////                                                   [_calls objectForKey:uuid], uuid, handle, [error localizedDescription]);
//                                   if ([error code] == CXErrorCodeIncomingCallErrorFilteredByDoNotDisturb ||
//                                      [error code] == CXErrorCodeIncomingCallErrorFilteredByBlockList)
//                                      linphone_call_decline(call,LinphoneReasonBusy); /*to give a chance for other devices to answer*/
//                                   else
//                                      linphone_call_decline(call,LinphoneReasonUnknown);
//                                }
//                             }];
//}
- (void)setPendingCall:(LinphoneCall *)pendingCall {
   if (pendingCall) {
@@ -127,177 +127,177 @@
#pragma mark - CXProviderDelegate Protocol
- (void)provider:(CXProvider *)provider performAnswerCallAction:(CXAnswerCallAction *)action {
    NSUUID *uuid = action.callUUID;
    NSString *callID = [self.calls objectForKey:uuid]; // first, make sure this callid is not already involved in a call
//   LOGD(@"CallKit: Answering call with call-id: [%@] and UUID: [%@]", callID, uuid);
   [self configAudioSession:[AVAudioSession sharedInstance]];
   [action fulfill];
   LinphoneCall *call = [HDLLinphoneManager.instance callByCallId:callID];
   if (!call)
      return;
//- (void)provider:(CXProvider *)provider performAnswerCallAction:(CXAnswerCallAction *)action {
//    NSUUID *uuid = action.callUUID;
//    NSString *callID = [self.calls objectForKey:uuid]; // first, make sure this callid is not already involved in a call
////   LOGD(@"CallKit: Answering call with call-id: [%@] and UUID: [%@]", callID, uuid);
//   [self configAudioSession:[AVAudioSession sharedInstance]];
//   [action fulfill];
//   LinphoneCall *call = [HDLLinphoneManager.instance callByCallId:callID];
//   if (!call)
//      return;
//
//   self.callKitCalls++;
//    self.pendingCall = call;
//}
   self.callKitCalls++;
    self.pendingCall = call;
}
- (void)provider:(CXProvider *)provider performStartCallAction:(CXStartCallAction *)action {
    NSUUID *uuid = action.callUUID;
    NSString *callID = [self.calls objectForKey:uuid]; // first, make sure this callid is not already involved in a call
   NSLog(@"CallKit: Starting Call with call-id: [%@] and UUID: [%@]", callID, uuid);
   // To restart Audio Unit
   [self configAudioSession:[AVAudioSession sharedInstance]];
   [action fulfill];
   LinphoneCall *call;
   if (![callID isEqualToString:@""]) {
      call = linphone_core_get_current_call(LC);
   } else {
      call = [HDLLinphoneManager.instance callByCallId:callID];
   }
   if (call != NULL) {
        self.callKitCalls++;
      self.pendingCall = call;
   }
}
- (void)provider:(CXProvider *)provider performEndCallAction:(CXEndCallAction *)action {
   self.callKitCalls--;
   [action fulfill];
   if (linphone_core_is_in_conference(LC)) {
      HDLLinphoneManager.instance.conf = TRUE;
      linphone_core_terminate_conference(LC);
//        LOGD(@"CallKit: Ending the conference");
   } else if (linphone_core_get_calls_nb(LC) > 1) {
      HDLLinphoneManager.instance.conf = TRUE;
      linphone_core_terminate_all_calls(LC);
//        LOGD(@"CallKit: Ending all the ongoing calls");
   } else {
      NSUUID *uuid = action.callUUID;
      NSString *callID = [self.calls objectForKey:uuid];
      if (callID) {
//            LOGD(@"CallKit: Ending the call with call-id: [%@] and UUID: [%@]", callID, uuid);
         LinphoneCall *call = [HDLLinphoneManager.instance callByCallId:callID];
         if (call) {
            linphone_call_terminate((LinphoneCall *)call);
         }
         [self.uuids removeObjectForKey:callID];
         [self.calls removeObjectForKey:uuid];
      }
   }
}
- (void)provider:(CXProvider *)provider performSetMutedCallAction:(nonnull CXSetMutedCallAction *)action {
   [action fulfill];
//   if ([[PhoneMainView.instance currentView] equal:CallView.compositeViewDescription]) {
//      CallView *view = (CallView *)[PhoneMainView.instance popToView:CallView.compositeViewDescription];
//      [view.microButton toggle];
//- (void)provider:(CXProvider *)provider performStartCallAction:(CXStartCallAction *)action {
//    NSUUID *uuid = action.callUUID;
//    NSString *callID = [self.calls objectForKey:uuid]; // first, make sure this callid is not already involved in a call
//   NSLog(@"CallKit: Starting Call with call-id: [%@] and UUID: [%@]", callID, uuid);
//   // To restart Audio Unit
//   [self configAudioSession:[AVAudioSession sharedInstance]];
//   [action fulfill];
//   LinphoneCall *call;
//   if (![callID isEqualToString:@""]) {
//      call = linphone_core_get_current_call(LC);
//   } else {
//      call = [HDLLinphoneManager.instance callByCallId:callID];
//   }
}
//   if (call != NULL) {
//        self.callKitCalls++;
//      self.pendingCall = call;
//   }
//}
- (void)provider:(CXProvider *)provider performSetHeldCallAction:(nonnull CXSetHeldCallAction *)action {
   [action fulfill];
   if (linphone_core_is_in_conference(LC) && action.isOnHold) {
      linphone_core_leave_conference(LC);
//        LOGD(@"CallKit: Leaving conference");
      [NSNotificationCenter.defaultCenter postNotificationName:kLinphoneCallUpdate object:self];
      return;
   }
//- (void)provider:(CXProvider *)provider performEndCallAction:(CXEndCallAction *)action {
//   self.callKitCalls--;
//   [action fulfill];
//   if (linphone_core_is_in_conference(LC)) {
//      HDLLinphoneManager.instance.conf = TRUE;
//      linphone_core_terminate_conference(LC);
////        LOGD(@"CallKit: Ending the conference");
//   } else if (linphone_core_get_calls_nb(LC) > 1) {
//      HDLLinphoneManager.instance.conf = TRUE;
//      linphone_core_terminate_all_calls(LC);
////        LOGD(@"CallKit: Ending all the ongoing calls");
//   } else {
//      NSUUID *uuid = action.callUUID;
//      NSString *callID = [self.calls objectForKey:uuid];
//      if (callID) {
////            LOGD(@"CallKit: Ending the call with call-id: [%@] and UUID: [%@]", callID, uuid);
//         LinphoneCall *call = [HDLLinphoneManager.instance callByCallId:callID];
//         if (call) {
//            linphone_call_terminate((LinphoneCall *)call);
//         }
//         [self.uuids removeObjectForKey:callID];
//         [self.calls removeObjectForKey:uuid];
//      }
//   }
//}
   if (linphone_core_get_calls_nb(LC) > 1 && action.isOnHold) {
      linphone_core_pause_all_calls(LC);
//        LOGD(@"CallKit: Pausing all ongoing calls");
      return;
   }
//- (void)provider:(CXProvider *)provider performSetMutedCallAction:(nonnull CXSetMutedCallAction *)action {
//   [action fulfill];
////   if ([[PhoneMainView.instance currentView] equal:CallView.compositeViewDescription]) {
////      CallView *view = (CallView *)[PhoneMainView.instance popToView:CallView.compositeViewDescription];
////      [view.microButton toggle];
////   }
//}
   NSUUID *uuid = action.callUUID;
   NSString *callID = [self.calls objectForKey:uuid];
   if (!callID) {
      return;
   }
//- (void)provider:(CXProvider *)provider performSetHeldCallAction:(nonnull CXSetHeldCallAction *)action {
//   [action fulfill];
//   if (linphone_core_is_in_conference(LC) && action.isOnHold) {
//      linphone_core_leave_conference(LC);
////        LOGD(@"CallKit: Leaving conference");
//      [NSNotificationCenter.defaultCenter postNotificationName:kLinphoneCallUpdate object:self];
//      return;
//   }
//
//   if (linphone_core_get_calls_nb(LC) > 1 && action.isOnHold) {
//      linphone_core_pause_all_calls(LC);
////        LOGD(@"CallKit: Pausing all ongoing calls");
//      return;
//   }
//
//   NSUUID *uuid = action.callUUID;
//   NSString *callID = [self.calls objectForKey:uuid];
//   if (!callID) {
//      return;
//   }
//
////    LOGD(@"CallKit: Call  with call-id: [%@] and UUID: [%@] paused status changed to: []", callID, uuid, action.isOnHold ? @"Paused" : @"Resumed");
//   LinphoneCall *call = [HDLLinphoneManager.instance callByCallId:callID];
//   if (!call)
//        return;
//
//   if (action.isOnHold) {
//      HDLLinphoneManager.instance.speakerBeforePause = HDLLinphoneManager.instance.speakerEnabled;
//      linphone_call_pause((LinphoneCall *)call);
//   } else {
//      if (linphone_core_get_conference(LC)) {
//         linphone_core_enter_conference(LC);
//         [NSNotificationCenter.defaultCenter postNotificationName:kLinphoneCallUpdate object:self];
//      } else {
//         [self configAudioSession:[AVAudioSession sharedInstance]];
//         self.pendingCall = call;
//      }
//   }
//}
//    LOGD(@"CallKit: Call  with call-id: [%@] and UUID: [%@] paused status changed to: []", callID, uuid, action.isOnHold ? @"Paused" : @"Resumed");
   LinphoneCall *call = [HDLLinphoneManager.instance callByCallId:callID];
   if (!call)
        return;
//- (void)provider:(CXProvider *)provider performPlayDTMFCallAction:(CXPlayDTMFCallAction *)action {
//   [action fulfill];
//   NSUUID *uuid = action.callUUID;
//   NSString *callID = [self.calls objectForKey:uuid];
////    LOGD(@"CallKit: playing DTMF for call with call-id: [%@] and UUID: [%@]", callID, uuid);
//   LinphoneCall *call = [HDLLinphoneManager.instance callByCallId:callID];
//   char digit = action.digits.UTF8String[0];
//   linphone_call_send_dtmf((LinphoneCall *)call, digit);
//}
   if (action.isOnHold) {
      HDLLinphoneManager.instance.speakerBeforePause = HDLLinphoneManager.instance.speakerEnabled;
      linphone_call_pause((LinphoneCall *)call);
   } else {
      if (linphone_core_get_conference(LC)) {
         linphone_core_enter_conference(LC);
         [NSNotificationCenter.defaultCenter postNotificationName:kLinphoneCallUpdate object:self];
      } else {
         [self configAudioSession:[AVAudioSession sharedInstance]];
         self.pendingCall = call;
      }
   }
}
//- (void)provider:(CXProvider *)provider didActivateAudioSession:(AVAudioSession *)audioSession {
//   NSLog(@"CallKit: Audio session activated");
//   // Now we can (re)start the call
//   if (self.pendingCall) {
//      LinphoneCallState state = linphone_call_get_state(self.pendingCall);
//      switch (state) {
//         case LinphoneCallIncomingReceived:
//            [HDLLinphoneManager.instance acceptCall:(LinphoneCall *)self.pendingCall evenWithVideo:_pendingCallVideo];
//            break;
//         case LinphoneCallPaused:
//            linphone_call_resume((LinphoneCall *)self.pendingCall);
//            break;
//         case LinphoneCallStreamsRunning:
//            // May happen when multiple calls
//            break;
//         default:
//            break;
//      }
//   } else {
//      if (_pendingAddr) {
//         [HDLLinphoneManager.instance doCall:_pendingAddr];
//      } else {
////         LOGE(@"CallKit: No pending call");
//      }
//   }
//
//    [self setPendingCall:NULL];
//   if (_pendingAddr)
//      linphone_address_unref(_pendingAddr);
//   _pendingAddr = NULL;
//   _pendingCallVideo = FALSE;
//}
//
//- (void)provider:(CXProvider *)provider didDeactivateAudioSession:(nonnull AVAudioSession *)audioSession {
//   NSLog(@"CallKit : Audio session deactivated");
//    [self setPendingCall:NULL];
//   if (_pendingAddr)
//      linphone_address_unref(_pendingAddr);
//   _pendingAddr = NULL;
//   _pendingCallVideo = FALSE;
//}
- (void)provider:(CXProvider *)provider performPlayDTMFCallAction:(CXPlayDTMFCallAction *)action {
   [action fulfill];
   NSUUID *uuid = action.callUUID;
   NSString *callID = [self.calls objectForKey:uuid];
//    LOGD(@"CallKit: playing DTMF for call with call-id: [%@] and UUID: [%@]", callID, uuid);
   LinphoneCall *call = [HDLLinphoneManager.instance callByCallId:callID];
   char digit = action.digits.UTF8String[0];
   linphone_call_send_dtmf((LinphoneCall *)call, digit);
}
- (void)provider:(CXProvider *)provider didActivateAudioSession:(AVAudioSession *)audioSession {
   NSLog(@"CallKit: Audio session activated");
   // Now we can (re)start the call
   if (self.pendingCall) {
      LinphoneCallState state = linphone_call_get_state(self.pendingCall);
      switch (state) {
         case LinphoneCallIncomingReceived:
            [HDLLinphoneManager.instance acceptCall:(LinphoneCall *)self.pendingCall evenWithVideo:_pendingCallVideo];
            break;
         case LinphoneCallPaused:
            linphone_call_resume((LinphoneCall *)self.pendingCall);
            break;
         case LinphoneCallStreamsRunning:
            // May happen when multiple calls
            break;
         default:
            break;
      }
   } else {
      if (_pendingAddr) {
         [HDLLinphoneManager.instance doCall:_pendingAddr];
      } else {
//         LOGE(@"CallKit: No pending call");
      }
   }
    [self setPendingCall:NULL];
   if (_pendingAddr)
      linphone_address_unref(_pendingAddr);
   _pendingAddr = NULL;
   _pendingCallVideo = FALSE;
}
- (void)provider:(CXProvider *)provider didDeactivateAudioSession:(nonnull AVAudioSession *)audioSession {
   NSLog(@"CallKit : Audio session deactivated");
    [self setPendingCall:NULL];
   if (_pendingAddr)
      linphone_address_unref(_pendingAddr);
   _pendingAddr = NULL;
   _pendingCallVideo = FALSE;
}
- (void)providerDidReset:(CXProvider *)provider {
//   LOGD(@"CallKit: Provider reset");
   HDLLinphoneManager.instance.conf = TRUE;
   linphone_core_terminate_all_calls(LC);
   [self.calls removeAllObjects];
   [self.uuids removeAllObjects];
}
#pragma mark - CXCallObserverDelegate Protocol
- (void)callObserver:(CXCallObserver *)callObserver callChanged:(CXCall *)call {
   NSLog(@"CallKit: Call changed");
}
//- (void)providerDidReset:(CXProvider *)provider {
////   LOGD(@"CallKit: Provider reset");
//   HDLLinphoneManager.instance.conf = TRUE;
//   linphone_core_terminate_all_calls(LC);
//   [self.calls removeAllObjects];
//   [self.uuids removeAllObjects];
//}
//
//#pragma mark - CXCallObserverDelegate Protocol
//
//- (void)callObserver:(CXCallObserver *)callObserver callChanged:(CXCall *)call {
//   NSLog(@"CallKit: Call changed");
//}
@end