diff --git a/Classes/CallManager.swift b/Classes/CallManager.swift index 2be08ed05..7cb376bc8 100644 --- a/Classes/CallManager.swift +++ b/Classes/CallManager.swift @@ -171,7 +171,7 @@ import AVFoundation let callInfo = providerDelegate.callInfos[uuid!] if (callInfo?.declined ?? false) { // This call was declined. - providerDelegate.reportIncomingCall(call:nil, uuid: uuid!, handle: "Calling", hasVideo: true) + providerDelegate.reportIncomingCall(call:nil, uuid: uuid!, handle: "Calling", hasVideo: true, displayName: callInfo?.displayName ?? "Calling") providerDelegate.endCall(uuid: uuid!) } return @@ -179,21 +179,22 @@ import AVFoundation let call = CallManager.instance().callByCallId(callId: callId) if (call != nil) { - let addr = FastAddressBook.displayName(for: call?.remoteAddress?.getCobject) ?? "Unknow" + let displayName = FastAddressBook.displayName(for: call?.remoteAddress?.getCobject) ?? "Unknow" let video = UIApplication.shared.applicationState == .active && (lc!.videoActivationPolicy?.automaticallyAccept ?? false) && (call!.remoteParams?.videoEnabled ?? false) - displayIncomingCall(call: call, handle: addr, hasVideo: video, callId: callId) + displayIncomingCall(call: call, handle: (call!.remoteAddress?.asStringUriOnly())!, hasVideo: video, callId: callId, displayName: displayName) } else { - displayIncomingCall(call: nil, handle: "Calling", hasVideo: true, callId: callId) + displayIncomingCall(call: nil, handle: "Calling", hasVideo: true, callId: callId, displayName: "Calling") } } - func displayIncomingCall(call:Call?, handle: String, hasVideo: Bool, callId: String) { + func displayIncomingCall(call:Call?, handle: String, hasVideo: Bool, callId: String, displayName:String) { let uuid = UUID() let callInfo = CallInfo.newIncomingCallInfo(callId: callId) providerDelegate.callInfos.updateValue(callInfo, forKey: uuid) providerDelegate.uuids.updateValue(uuid, forKey: callId) - providerDelegate.reportIncomingCall(call:call, uuid: uuid, handle: handle, hasVideo: hasVideo) + providerDelegate.reportIncomingCall(call:call, uuid: uuid, handle: handle, hasVideo: hasVideo, displayName: displayName) + } @objc func acceptCall(call: OpaquePointer?, hasVideo:Bool) { @@ -240,11 +241,11 @@ import AVFoundation if (CallManager.callKitEnabled() && !CallManager.instance().nextCallIsTransfer) { let uuid = UUID() let name = FastAddressBook.displayName(for: addr) ?? "unknow" - let handle = CXHandle(type: .generic, value: name) + let handle = CXHandle(type: .generic, value: sAddr.asStringUriOnly()) let startCallAction = CXStartCallAction(call: uuid, handle: handle) let transaction = CXTransaction(action: startCallAction) - let callInfo = CallInfo.newOutgoingCallInfo(addr: sAddr, isSas: isSas) + let callInfo = CallInfo.newOutgoingCallInfo(addr: sAddr, isSas: isSas, displayName: name) providerDelegate.callInfos.updateValue(callInfo, forKey: uuid) providerDelegate.uuids.updateValue(uuid, forKey: "") @@ -406,10 +407,31 @@ import AVFoundation } } } + + @objc func performActionWhenCoreIsOn(action: @escaping ()->Void ) { + if (manager.globalState == .On) { + action() + } else { + manager.actionsToPerformOnceWhenCoreIsOn.append(action) + } + } + } class CoreManagerDelegate: CoreDelegate { static var speaker_already_enabled : Bool = false + var globalState : GlobalState = .Off + var actionsToPerformOnceWhenCoreIsOn : [(()->Void)] = [] + + override func onGlobalStateChanged(lc: Core, gstate: GlobalState, message: String) { + if (gstate == .On) { + actionsToPerformOnceWhenCoreIsOn.forEach { + $0() + } + actionsToPerformOnceWhenCoreIsOn.removeAll() + } + globalState = gstate + } override func onRegistrationStateChanged(lc: Core, cfg: ProxyConfig, cstate: RegistrationState, message: String) { if lc.proxyConfigList.count == 1 && (cstate == .Failed || cstate == .Cleared){ @@ -425,7 +447,7 @@ class CoreManagerDelegate: CoreDelegate { override func onCallStateChanged(lc: Core, call: Call, cstate: Call.State, message: String) { let addr = call.remoteAddress; - let address = FastAddressBook.displayName(for: addr?.getCobject) ?? "Unknow" + let displayName = FastAddressBook.displayName(for: addr?.getCobject) ?? "Unknow" let callLog = call.callLog let callId = callLog?.callId let video = UIApplication.shared.applicationState == .active && (lc.videoActivationPolicy?.automaticallyAccept ?? false) && (call.remoteParams?.videoEnabled ?? false) @@ -445,7 +467,7 @@ class CoreManagerDelegate: CoreDelegate { let uuid = CallManager.instance().providerDelegate.uuids["\(callId!)"] if (uuid != nil) { // Tha app is now registered, updated the call already existed. - CallManager.instance().providerDelegate.updateCall(uuid: uuid!, handle: address, hasVideo: video) + CallManager.instance().providerDelegate.updateCall(uuid: uuid!, handle: addr!.asStringUriOnly(), hasVideo: video, displayName: displayName) let callInfo = CallManager.instance().providerDelegate.callInfos[uuid!] if (callInfo?.declined ?? false) { DispatchQueue.main.asyncAfter(deadline: .now()) {try? call.decline(reason: callInfo!.reason)} @@ -454,13 +476,13 @@ class CoreManagerDelegate: CoreDelegate { CallManager.instance().acceptCall(call: call, hasVideo: video) } } else { - CallManager.instance().displayIncomingCall(call: call, handle: address, hasVideo: video, callId: callId!) + CallManager.instance().displayIncomingCall(call: call, handle: addr!.asStringUriOnly(), hasVideo: video, callId: callId!, displayName: displayName) } } else if (UIApplication.shared.applicationState != .active) { // not support callkit , use notif let content = UNMutableNotificationContent() content.title = NSLocalizedString("Incoming call", comment: "") - content.body = address + content.body = displayName content.sound = UNNotificationSound.init(named: UNNotificationSoundName.init("notes_of_the_optimistic.caf")) content.categoryIdentifier = "call_cat" content.userInfo = ["CallId" : callId!] @@ -524,7 +546,7 @@ class CoreManagerDelegate: CoreDelegate { // Configure the notification's payload. let content = UNMutableNotificationContent() content.title = NSString.localizedUserNotificationString(forKey: NSLocalizedString("Missed call", comment: ""), arguments: nil) - content.body = NSString.localizedUserNotificationString(forKey: address, arguments: nil) + content.body = NSString.localizedUserNotificationString(forKey: displayName, arguments: nil) // Deliver the notification. let request = UNNotificationRequest(identifier: "call_request", content: content, trigger: nil) // Schedule the notification. diff --git a/Classes/LinphoneAppDelegate.m b/Classes/LinphoneAppDelegate.m index 8a600ecf3..a1aa761c4 100644 --- a/Classes/LinphoneAppDelegate.m +++ b/Classes/LinphoneAppDelegate.m @@ -31,6 +31,9 @@ #include "LinphoneManager.h" #include "linphone/linphonecore.h" +#import +#import + #ifdef USE_CRASHLYTICS #include "FIRApp.h" #endif @@ -256,7 +259,6 @@ #ifdef USE_CRASHLYTICS [FIRApp configure]; #endif - UIApplication *app = [UIApplication sharedApplication]; UIApplicationState state = app.applicationState; @@ -404,11 +406,24 @@ // used for callkit. Called when active video. - (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity restorationHandler:(nonnull void (^)(NSArray> * _Nullable))restorationHandler { + + if ([userActivity.activityType isEqualToString:@"INStartVideoCallIntent"]) { LOGI(@"CallKit: satrt video."); CallView *view = VIEW(CallView); [view.videoButton setOn]; } + if ([userActivity.activityType isEqualToString:@"INStartAudioCallIntent"]) { // tel URI handler. + INInteraction *interaction = userActivity.interaction; + INStartAudioCallIntent *startAudioCallIntent = (INStartAudioCallIntent *)interaction.intent; + INPerson *contact = startAudioCallIntent.contacts[0]; + INPersonHandle *personHandle = contact.personHandle; + [CallManager.instance performActionWhenCoreIsOnAction:^(void) { + [LinphoneManager.instance call: [LinphoneUtils normalizeSipOrPhoneAddress:personHandle.value]]; + }]; + + } + return YES; } diff --git a/Classes/ProviderDelegate.swift b/Classes/ProviderDelegate.swift index 2fa978f2b..1b7fdd467 100644 --- a/Classes/ProviderDelegate.swift +++ b/Classes/ProviderDelegate.swift @@ -33,6 +33,7 @@ import os var declined = false var connected = false var reason: Reason = Reason.None + var displayName: String? static func newIncomingCallInfo(callId: String) -> CallInfo { let callInfo = CallInfo() @@ -40,11 +41,12 @@ import os return callInfo } - static func newOutgoingCallInfo(addr: Address, isSas: Bool) -> CallInfo { + static func newOutgoingCallInfo(addr: Address, isSas: Bool, displayName: String) -> CallInfo { let callInfo = CallInfo() callInfo.isOutgoing = true callInfo.sasEnabled = isSas callInfo.toAddr = addr + callInfo.displayName = displayName return callInfo } } @@ -68,7 +70,7 @@ class ProviderDelegate: NSObject { providerConfiguration.ringtoneSound = "notes_of_the_optimistic.caf" providerConfiguration.supportsVideo = true providerConfiguration.iconTemplateImageData = UIImage(named: "callkit_logo")?.pngData() - providerConfiguration.supportedHandleTypes = [.generic] + providerConfiguration.supportedHandleTypes = [.generic, .phoneNumber, .emailAddress] providerConfiguration.maximumCallsPerCallGroup = 10 providerConfiguration.maximumCallGroups = 2 @@ -79,10 +81,11 @@ class ProviderDelegate: NSObject { return providerConfiguration }() - func reportIncomingCall(call:Call?, uuid: UUID, handle: String, hasVideo: Bool) { + func reportIncomingCall(call:Call?, uuid: UUID, handle: String, hasVideo: Bool, displayName:String) { let update = CXCallUpdate() update.remoteHandle = CXHandle(type:.generic, value: handle) update.hasVideo = hasVideo + update.localizedCallerName = displayName let callInfo = callInfos[uuid] let callId = callInfo?.callId @@ -112,9 +115,10 @@ class ProviderDelegate: NSObject { } } - func updateCall(uuid: UUID, handle: String, hasVideo: Bool = false) { + func updateCall(uuid: UUID, handle: String, hasVideo: Bool = false, displayName:String) { let update = CXCallUpdate() update.remoteHandle = CXHandle(type:.generic, value:handle) + update.localizedCallerName = displayName update.hasVideo = hasVideo provider.reportCall(with:uuid, updated:update); } @@ -221,9 +225,17 @@ extension ProviderDelegate: CXProviderDelegate { } func provider(_ provider: CXProvider, perform action: CXStartCallAction) { + + do { + let uuid = action.callUUID let callInfo = callInfos[uuid] + let update = CXCallUpdate() + update.remoteHandle = action.handle + update.localizedCallerName = callInfo?.displayName + self.provider.reportCall(with: action.callUUID, updated: update) + let addr = callInfo?.toAddr if (addr == nil) { Log.directLog(BCTBX_LOG_ERROR, text: "CallKit: can not call a null address!")