464027401@qq.com
2021-09-27 b469805b2d0c9b23ca020cf9356ff137205f856c
修复来点页面重复呼叫时alert位置不对问题
11个文件已修改
699 ■■■■■ 已修改文件
HDLLinPhoneSDK(OC)/HDLLinPhoneSDK.xcodeproj/project.pbxproj 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLLinPhoneSDK(OC)/HDLLinPhoneSDK.xcodeproj/xcshareddata/xcschemes/HDLLinPhoneSDK.xcscheme 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLLinPhoneSDK(OC)/HDLLinPhoneSDK/HDLLPOnMonitorViewController.m 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLLinPhoneSDK(OC)/HDLLinPhoneSDK/HDLLinPhoneCommon.h 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLLinPhoneSDK(OC)/HDLLinPhoneSDK/HDLLinPhoneCommon.m 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLLinPhoneSDK(OC)/HDLLinPhoneSDK/HDLLinPhoneSDK.m 86 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLLinPhoneSDK(OC)/HDLLinPhoneSDK/HDLLinphoneIntercomVC.m 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLLinPhoneSDK(OC)/HDLLinPhoneSDK/HDLLinphoneManager.m 109 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLLinPhoneSDK(OC)/HDLLinPhoneSDK/HDLLinphoneProviderDelegate.h 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLLinPhoneSDK(OC)/HDLLinPhoneSDK/HDLLinphoneProviderDelegate.m 418 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Shared.IOS.HDLLinphoneSDK/Shared.IOS.HDLLinphoneSDK/Library/libHDLLinPhoneSDK.a 补丁 | 查看 | 原始文档 | blame | 历史
HDLLinPhoneSDK£¨OC£©/HDLLinPhoneSDK.xcodeproj/project.pbxproj
@@ -375,6 +375,7 @@
        AE9CC93926B8DD3F00FD514C /* Debug */ = {
            isa = XCBuildConfiguration;
            buildSettings = {
                ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO;
                CODE_SIGN_STYLE = Automatic;
                DEVELOPMENT_TEAM = V39C74NPHU;
                ENABLE_BITCODE = NO;
@@ -398,6 +399,7 @@
        AE9CC93A26B8DD3F00FD514C /* Release */ = {
            isa = XCBuildConfiguration;
            buildSettings = {
                ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO;
                CODE_SIGN_STYLE = Automatic;
                DEVELOPMENT_TEAM = V39C74NPHU;
                ENABLE_BITCODE = NO;
HDLLinPhoneSDK£¨OC£©/HDLLinPhoneSDK.xcodeproj/xcshareddata/xcschemes/HDLLinPhoneSDK.xcscheme
@@ -31,7 +31,7 @@
      </Testables>
   </TestAction>
   <LaunchAction
      buildConfiguration = "Debug"
      buildConfiguration = "Release"
      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
      launchStyle = "0"
HDLLinPhoneSDK£¨OC£©/HDLLinPhoneSDK/HDLLPOnMonitorViewController.m
@@ -10,7 +10,7 @@
#import <Photos/Photos.h>
#import "HDLLinphoneUtlis.h"
#import "HDLLinphoneManager.h"
#import "HDLLinPhoneCommon.h"
//#import "HDLLinPhoneSDK-Swift.h"
//#import "LCUtlis.h"
//#import "LCApiKit.h"
@@ -37,7 +37,7 @@
@property (nonatomic,strong) dispatch_source_t openDoorTimer;
@property (nonatomic, assign) int openDoorTimeout;
@property (nonatomic, assign)  BOOL isHangUpByRemote;//是否对方远程挂断
/// æ’­æ”¾å™¨
//@property (nonatomic, strong) LCOpenSDK_PlayWindow *playWindow;
@@ -101,6 +101,7 @@
    int state = [[notif.userInfo objectForKey:@"state"] intValue];
    if ((state == LinphoneCallEnd || state == LinphoneCallError)){//挂断了
        NSLog(@"挂断或出错了");
        self.isHangUpByRemote=YES;
        [self showUIAlertViewWithBack:@"监视结束"];
        
    }
@@ -450,8 +451,9 @@
    [alertController addAction:[UIAlertAction actionWithTitle:okStr style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        [self backAction];
    }]];
    [self presentViewController:alertController animated:YES completion:nil];
//    [[HDLLinPhoneCommon rootController] presentViewController:alertController animated:YES completion:nil];
}
@@ -469,14 +471,16 @@
- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    
}
-(void)viewWillDisappear:(BOOL)animated{
    [super viewWillDisappear:animated];
    
    //1.暂停SDK相关播放
    [self stopPlay];
    if (!self.isHangUpByRemote) {
        [self stopPlay];
    }
    //2.Delegate释放
//    self.mLCCallDelegate = nil;
    //3.定时器释放
HDLLinPhoneSDK£¨OC£©/HDLLinPhoneSDK/HDLLinPhoneCommon.h
@@ -12,6 +12,8 @@
@interface HDLLinPhoneCommon : NSObject
+(UIViewController *) topMostController;//获取顶层视图
+(UIViewController *) rootController;//获取根控制器
+(BOOL)rootPresentVCContent:(Class)vcClass;//判断所有present的控制器是否含有VC
+(UIWindow*)appWindow;
+(NSString *)temporarySaveImagePath;//临时保存图片的路劲
+(void)saveImageToPhotosAlbum:(UIImage *)savedImage;//保存图片到相册
HDLLinPhoneSDK£¨OC£©/HDLLinPhoneSDK/HDLLinPhoneCommon.m
@@ -22,6 +22,37 @@
    return topController;
}
+(UIViewController *) rootController {
    UIViewController*topController ;
    if ([UIApplication sharedApplication].delegate.window) {
        topController= [UIApplication sharedApplication].delegate.window.rootViewController;
    }else{
        topController=[self appWindow].rootViewController;
    }
//    while(topController.presentedViewController){
//        topController=topController.presentedViewController;
//    }
    return topController;
}
+(BOOL)rootPresentVCContent:(Class)vcClass{
    UIViewController*roootVC ;
    if ([UIApplication sharedApplication].delegate.window) {
        roootVC= [UIApplication sharedApplication].delegate.window.rootViewController;
    }else{
        roootVC=[self appWindow].rootViewController;
    }
    while(roootVC.presentedViewController){
        if ([roootVC.presentedViewController isKindOfClass:vcClass]) {
            return YES;
            break;
        }
        roootVC=roootVC.presentedViewController;
    }
    return NO;
}
+(UIWindow*)appWindow{
    UIWindow *window;
    if (@available(iOS 13.0, *)) {
HDLLinPhoneSDK£¨OC£©/HDLLinPhoneSDK/HDLLinPhoneSDK.m
@@ -13,7 +13,7 @@
#import "HDLLPOnMonitorViewController.h"
@interface HDLLinPhoneSDK()
@property (strong, nonatomic) HDLLinphoneIntercomVC* presentingIntercomVC;//当前展示的来点控制器,用于存放正在展示的来点控制器,避免重复弹出界面
@end
@implementation HDLLinPhoneSDK
@@ -70,18 +70,19 @@
    if (state == LinphoneCallIncomingReceived) {
        [self.hdlLinphoneCallDelegate onIncomingCall:userName];
        if(self.IsAutoJumpCallView){
//                    NSString *callId=[NSString stringWithFormat:@"%@",[notif.userInfo objectForKey:@"callID"]];
//                    BOOL hasVideo=(BOOL)[notif.userInfo objectForKey:@"hasVideo"];
            
                    HDLLinphoneIntercomVC *vc=[[HDLLinphoneIntercomVC alloc]init];
//                    vc.CallId=callId;
                    vc.hasVideo=YES;
                    vc.hdlLinphoneCallDelegate=self.hdlLinphoneCallDelegate;
                    vc.modalPresentationStyle = UIModalPresentationFullScreen;
//                    self.IntercomVC=vc;
                    [[HDLLinPhoneCommon topMostController] presentViewController:vc animated:YES completion:^{
//                    HDLLinphoneIntercomVC *vc=[[HDLLinphoneIntercomVC alloc]init];
////                    vc.CallId=callId;
//                    vc.hasVideo=YES;
//                    vc.hdlLinphoneCallDelegate=self.hdlLinphoneCallDelegate;
//                    vc.modalPresentationStyle = UIModalPresentationFullScreen;
////                    self.IntercomVC=vc;
//                    [[HDLLinPhoneCommon topMostController] presentViewController:vc animated:YES completion:^{
//
//                    }];
            
                    }];
            [self gotoHDLLinphoneIntercomVC:nil];
        }
    }
}
@@ -114,16 +115,73 @@
    
//    NSString *callId=[NSString stringWithFormat:@"%@",[notif.userInfo objectForKey:@"callID"]];
//    BOOL hasVideo=(BOOL)[notif.userInfo objectForKey:@"hasVideo"];
//    NSLog(@"顶层视图:%@",[HDLLinPhoneCommon topMostController]);
    if ([HDLLinPhoneCommon rootPresentVCContent:[HDLLinphoneIntercomVC class]]||[HDLLinPhoneCommon rootPresentVCContent:[HDLLPOnMonitorViewController class]]) {
        if ([[HDLLinPhoneCommon topMostController] isKindOfClass:[UIAlertController class]]) {
            NSLog(@"顶层视图是视频通话页");
            __weak typeof(self) weakSelf = self;
            [[HDLLinPhoneCommon topMostController] dismissViewControllerAnimated:NO completion:^{
                UIViewController *topVC=[HDLLinPhoneCommon topMostController];
                if ([topVC isKindOfClass:[HDLLPOnMonitorViewController class]]) {
                    [topVC dismissViewControllerAnimated:NO completion:^{
                        [weakSelf toLinphoneIntercomVC:titleName];
                    }];
                }else if ([topVC isKindOfClass:[HDLLinphoneIntercomVC class]]) {
                    [topVC dismissViewControllerAnimated:NO completion:^{
                        [weakSelf toLinphoneIntercomVC:titleName];
                    }];
                }
            }];
        }
//        UIViewController *topVC=[HDLLinPhoneCommon topMostController];
//        if ([topVC isKindOfClass:[HDLLinphoneIntercomVC class]]) {
//            [topVC dismissViewControllerAnimated:NO completion:nil];
//        }
        return;
    }
    [self toLinphoneIntercomVC:titleName];
//    if (self.presentingIntercomVC) {
//        __weak typeof(self) weakSelf = self;
//        [self.presentingIntercomVC dismissViewControllerAnimated:NO completion:^{
//            NSLog(@"页面退出了");
//            weakSelf.presentingIntercomVC=nil;
//            [weakSelf toLinphoneIntercomVC:titleName];
//        }];
//
//        return;
//    }
//    NSLog(@"执行到我了");
//    [self toLinphoneIntercomVC:titleName];
//    HDLLinphoneIntercomVC *vc=[[HDLLinphoneIntercomVC alloc]init];
////    vc.CallId=callId;
//    vc.hasVideo=YES;
//    vc.hdlLinphoneCallDelegate=self.hdlLinphoneCallDelegate;
//    if (titleName) {
//        vc.titleName=titleName;
//    }
//    vc.modalPresentationStyle = UIModalPresentationFullScreen;
//    self.presentingIntercomVC=vc;
//    [[HDLLinPhoneCommon topMostController] presentViewController:vc animated:YES completion:^{
//
//    }];
}
-(void)toLinphoneIntercomVC:(NSString*)titleName{
    HDLLinphoneIntercomVC *vc=[[HDLLinphoneIntercomVC alloc]init];
//    vc.CallId=callId;
    vc.hasVideo=YES;
    vc.hdlLinphoneCallDelegate=self.hdlLinphoneCallDelegate;
    vc.titleName=titleName;
    if (titleName) {
        vc.titleName=titleName;
    }
    vc.modalPresentationStyle = UIModalPresentationFullScreen;
//    self.IntercomVC=vc;
//    self.presentingIntercomVC=vc;
    [[HDLLinPhoneCommon topMostController] presentViewController:vc animated:YES completion:^{
    }];
}
HDLLinPhoneSDK£¨OC£©/HDLLinPhoneSDK/HDLLinphoneIntercomVC.m
@@ -35,6 +35,9 @@
@property (nonatomic,strong) dispatch_source_t openDoorTimer;
@property (nonatomic, assign) int openDoorTimeout;
@property (nonatomic, assign) int callTimeout;
@property (nonatomic, assign)  BOOL isHangUpByRemote;//是否对方远程挂断
@end
@implementation HDLLinphoneIntercomVC{
@@ -90,11 +93,15 @@
}
- (void)linphoneCallUpdate:(NSNotification *)notif {
    int state = [[notif.userInfo objectForKey:@"state"] intValue];
    if ((state == LinphoneCallEnd || state == LinphoneCallError)) {//挂断了
    if ((state == LinphoneCallEnd || state == LinphoneCallError)) {//挂断了(虽然自己挂断也会走LinphoneCallUpdate通知,但自己挂断的话页面已销毁,不会触发该方法)
        NSLog(@"挂断或出错了");
        [self stopPlaySystemSound];
        self.isHangUpByRemote=YES;
        [self showUIAlertViewWithBack:@"通话结束"];
        
    }
}
@@ -331,6 +338,7 @@
    }
    return _hangUpTextBtn;
}
//接听 å›¾æ ‡æŒ‰é’®
- (UIButton *)answerImgBtn{
    if (_answerImgBtn == nil) {
@@ -653,7 +661,9 @@
    [self stopPlaySystemSound];
    //防止用户不按挂断,或者不等收到对方的挂断,点击返回按钮。
    //1.暂停SDK相关播放
    [self stopPlay];
    if (!self.isHangUpByRemote) {
        [self stopPlay];
    }
    //2.Delegate释放
    self.hdlLinphoneCallDelegate = nil;
    //3.定时器释放
@@ -672,8 +682,8 @@
}
-(void)dealloc{
    NSLog(@"==============dealloc  1");
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    NSLog(@"==============dealloc å¯¹è±¡é”€æ¯äº†");
//    [[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)willEnterForeground:(NSNotification*)notification{
    NSLog(@"willEnterForeground");
HDLLinPhoneSDK£¨OC£©/HDLLinPhoneSDK/HDLLinphoneManager.m
@@ -559,6 +559,8 @@
    linphone_core_set_preferred_video_size([HDLLinphoneManager getLc], vsize);
    linphone_core_set_video_preset([HDLLinphoneManager getLc], [@"custom" UTF8String]);
    linphone_core_set_preferred_framerate([HDLLinphoneManager getLc], 5);
//    linphone_core_enable_video_capture([HDLLinphoneManager getLc], false);
//    linphone_core_enable_video_preview([HDLLinphoneManager getLc], FALSE);
}
@@ -1063,45 +1065,45 @@
                : @"";
            NSUUID *uuid = (NSUUID *)[self.providerDelegate.uuids objectForKey:callId2];
            if (uuid) {
                LinphoneCall *callKit_call = (LinphoneCall *)linphone_core_get_calls(LC)
                LinphoneCall *callK_call = (LinphoneCall *)linphone_core_get_calls(LC)
                    ? linphone_core_get_calls(LC)->data
                    : NULL;
                const char *callKit_callId = callKit_call
                    ? linphone_call_log_get_call_id(linphone_call_get_call_log(callKit_call))
                const char *call_callId = callK_call
                    ? linphone_call_log_get_call_id(linphone_call_get_call_log(callK_call))
                    : NULL;
                if (callKit_callId && !_conf) {
                if (call_callId && !_conf) {
                    // Create a CallKit call because there's not !
                    NSString *callKit_callIdNS = [NSString stringWithUTF8String:callKit_callId];
                    NSUUID *callKit_uuid = [NSUUID UUID];
                    [HDLLinphoneManager.instance.providerDelegate.uuids setObject:callKit_uuid forKey:callKit_callIdNS];
                    [HDLLinphoneManager.instance.providerDelegate.calls setObject:callKit_callIdNS forKey:callKit_uuid];
                    NSString *callK_callIdNS = [NSString stringWithUTF8String:call_callId];
                    NSUUID *callK_uuid = [NSUUID UUID];
                    [HDLLinphoneManager.instance.providerDelegate.uuids setObject:callK_uuid forKey:callK_callIdNS];
                    [HDLLinphoneManager.instance.providerDelegate.calls setObject:callK_callIdNS forKey:callK_uuid];
//                    NSString *address = [FastAddressBook displayNameForAddress:linphone_call_get_remote_address(callKit_call)];
                    NSString *address=@"";
                    CXHandle *handle = [[CXHandle alloc] initWithType:CXHandleTypeGeneric value:address];
                    CXStartCallAction *act = [[CXStartCallAction alloc] initWithCallUUID:callKit_uuid handle:handle];
                    CXTransaction *tr = [[CXTransaction alloc] initWithAction:act];
                    [HDLLinphoneManager.instance.providerDelegate.controller requestTransaction:tr completion:^(NSError *err){}];
                    [HDLLinphoneManager.instance.providerDelegate.provider reportOutgoingCallWithUUID:callKit_uuid startedConnectingAtDate:nil];
                    [HDLLinphoneManager.instance.providerDelegate.provider reportOutgoingCallWithUUID:callKit_uuid connectedAtDate:nil];
//                    NSString *address=@"";
//                    CXHandle *handle = [[CXHandle alloc] initWithType:CXHandleTypeGeneric value:address];
//                    CXStartCallAction *act = [[CXStartCallAction alloc] initWithCallUUID:callKit_uuid handle:handle];
//                    CXTransaction *tr = [[CXTransaction alloc] initWithAction:act];
//                    [HDLLinphoneManager.instance.providerDelegate.controller requestTransaction:tr completion:^(NSError *err){}];
//                    [HDLLinphoneManager.instance.providerDelegate.provider reportOutgoingCallWithUUID:callKit_uuid startedConnectingAtDate:nil];
//                    [HDLLinphoneManager.instance.providerDelegate.provider reportOutgoingCallWithUUID:callKit_uuid connectedAtDate:nil];
                }
                CXEndCallAction *act = [[CXEndCallAction alloc] initWithCallUUID:uuid];
                CXTransaction *tr = [[CXTransaction alloc] initWithAction:act];
                [HDLLinphoneManager.instance.providerDelegate.controller requestTransaction:tr completion:^(NSError *err){}];
                LOGI(@"CallKit - clearing CK as call ended on uuid %@",uuid);
                [HDLLinphoneManager.instance.providerDelegate.provider reportOutgoingCallWithUUID:uuid connectedAtDate:[NSDate date]];
                [self.providerDelegate.uuids removeObjectForKey:callId2];
                [self.providerDelegate.calls removeObjectForKey:uuid];
                [self.providerDelegate.provider reportCallWithUUID:uuid endedAtDate:[NSDate date] reason:(state == LinphoneCallError ? CXCallEndedReasonFailed : CXCallEndedReasonRemoteEnded)];
//                CXEndCallAction *act = [[CXEndCallAction alloc] initWithCallUUID:uuid];
//                CXTransaction *tr = [[CXTransaction alloc] initWithAction:act];
//                [HDLLinphoneManager.instance.providerDelegate.controller requestTransaction:tr completion:^(NSError *err){}];
//                LOGI(@"CallKit - clearing CK as call ended on uuid %@",uuid);
//                [HDLLinphoneManager.instance.providerDelegate.provider reportOutgoingCallWithUUID:uuid connectedAtDate:[NSDate date]];
//                [self.providerDelegate.uuids removeObjectForKey:callId2];
//                [self.providerDelegate.calls removeObjectForKey:uuid];
//                [self.providerDelegate.provider reportCallWithUUID:uuid endedAtDate:[NSDate date] reason:(state == LinphoneCallError ? CXCallEndedReasonFailed : CXCallEndedReasonRemoteEnded)];
            } else { // Can happen when Call-ID changes (Replaces header)
                if (linphone_core_get_calls_nb(LC) ==0) { // Need to clear all CK calls
                    for (NSUUID *myUuid in self.providerDelegate.calls) {
                        [self.providerDelegate.provider reportCallWithUUID:myUuid
                         endedAtDate:NULL
                         reason:(state == LinphoneCallError
                             ? CXCallEndedReasonFailed
                             : CXCallEndedReasonRemoteEnded)];
                    }
//                    for (NSUUID *myUuid in self.providerDelegate.calls) {
//                        [self.providerDelegate.provider reportCallWithUUID:myUuid
//                         endedAtDate:NULL
//                         reason:(state == LinphoneCallError
//                             ? CXCallEndedReasonFailed
//                             : CXCallEndedReasonRemoteEnded)];
//                    }
                    [self.providerDelegate.uuids removeAllObjects];
                    [self.providerDelegate.calls removeAllObjects];
                }
@@ -2804,29 +2806,30 @@
        return;
    }
    if (linphone_core_get_calls_nb(theLinphoneCore) < 1 &&
        floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_9_x_Max &&
        self.providerDelegate.callKitCalls < 1) {
        NSLog(@"进这里呼叫了");
        self.providerDelegate.callKitCalls++;
        NSUUID *uuid = [NSUUID UUID];
        [HDLLinphoneManager.instance.providerDelegate.uuids setObject:uuid forKey:@""];
        [HDLLinphoneManager.instance.providerDelegate.calls setObject:@"" forKey:uuid];
        HDLLinphoneManager.instance.providerDelegate.pendingAddr = linphone_address_clone(iaddr);
//        NSString *address = [FastAddressBook displayNameForAddress:iaddr];
        NSString *address =@"unknow";
        CXHandle *handle = [[CXHandle alloc] initWithType:CXHandleTypeGeneric value:address];
        CXStartCallAction *act = [[CXStartCallAction alloc] initWithCallUUID:uuid handle:handle];
        CXTransaction *tr = [[CXTransaction alloc] initWithAction:act];
        [HDLLinphoneManager.instance.providerDelegate.controller requestTransaction:tr
         completion:^(NSError *err){
            NSLog(@"呼叫error:%@",err);
            }];
    } else {
        NSLog(@"进doCall呼叫了");
        [self doCall:iaddr];
    }
//    if (linphone_core_get_calls_nb(theLinphoneCore) < 1 &&
//        floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_9_x_Max &&
//        self.providerDelegate.callKitCalls < 1) {
//        NSLog(@"进这里呼叫了");
//        self.providerDelegate.callKitCalls++;
//        NSUUID *uuid = [NSUUID UUID];
//        [HDLLinphoneManager.instance.providerDelegate.uuids setObject:uuid forKey:@""];
//        [HDLLinphoneManager.instance.providerDelegate.calls setObject:@"" forKey:uuid];
//        HDLLinphoneManager.instance.providerDelegate.pendingAddr = linphone_address_clone(iaddr);
////        NSString *address = [FastAddressBook displayNameForAddress:iaddr];
//        NSString *address =@"unknow";
//
//        CXHandle *handle = [[CXHandle alloc] initWithType:CXHandleTypeGeneric value:address];
//        CXStartCallAction *act = [[CXStartCallAction alloc] initWithCallUUID:uuid handle:handle];
//        CXTransaction *tr = [[CXTransaction alloc] initWithAction:act];
//        [HDLLinphoneManager.instance.providerDelegate.controller requestTransaction:tr
//         completion:^(NSError *err){
//            NSLog(@"呼叫error:%@",err);
//            }];
//    } else {
//        NSLog(@"进doCall呼叫了");
//        [self doCall:iaddr];
//    }
    [self doCall:iaddr];
}
- (BOOL)doCall:(const LinphoneAddress *)iaddr {
HDLLinPhoneSDK£¨OC£©/HDLLinPhoneSDK/HDLLinphoneProviderDelegate.h
@@ -16,23 +16,24 @@
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
#import <CallKit/CallKit.h>
#import <Foundation/Foundation.h>
//#import <CallKit/CallKit.h>
#import <AVFoundation/AVAudioSession.h>
#include <linphone/core.h>
#ifndef ProviderDelegate_h
#define ProviderDelegate_h
@interface HDLLinphoneProviderDelegate : NSObject <CXProviderDelegate, CXCallObserverDelegate>
@property CXProvider *provider;
@property CXCallObserver *observer;
@property CXCallController *controller;
@interface HDLLinphoneProviderDelegate : NSObject
// <CXProviderDelegate, CXCallObserverDelegate>
//@property CXProvider *provider;
//@property CXCallObserver *observer;
//@property CXCallController *controller;
@property NSMutableDictionary *calls;
@property NSMutableDictionary *uuids;
@property(nonatomic) LinphoneCall *pendingCall;
@property LinphoneAddress *pendingAddr;
@property BOOL pendingCallVideo;
@property int callKitCalls;
@property int callKCalls;
- (void)reportIncomingCall:(LinphoneCall *) call withUUID:(NSUUID *)uuid handle:(NSString *)handle video:(BOOL)video;
- (void)config;
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
Shared.IOS.HDLLinphoneSDK/Shared.IOS.HDLLinphoneSDK/Library/libHDLLinPhoneSDK.a
Binary files differ