diff --git a/Classes/Swift/CallManager.swift b/Classes/Swift/CallManager.swift
index 429b678bf..07f38e44a 100644
--- a/Classes/Swift/CallManager.swift
+++ b/Classes/Swift/CallManager.swift
@@ -1,21 +1,21 @@
/*
-* Copyright (c) 2010-2020 Belledonne Communications SARL.
-*
-* This file is part of linphone-iphone
-*
-* This program is free software: you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation, either version 3 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program. If not, see .
-*/
+ * Copyright (c) 2010-2020 Belledonne Communications SARL.
+ *
+ * This file is part of linphone-iphone
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
import Foundation
import linphonesw
@@ -28,13 +28,13 @@ import AVFoundation
@objc var batteryWarningShown = false
@objc var videoRequested = false /*set when user has requested for video*/
@objc var isConference = false
-
+
}
/*
-* CallManager is a class that manages application calls and supports callkit.
-* There is only one CallManager by calling CallManager.instance().
-*/
+ * CallManager is a class that manages application calls and supports callkit.
+ * There is only one CallManager by calling CallManager.instance().
+ */
@objc class CallManager: NSObject, CoreDelegate {
static var theCallManager: CallManager?
let providerDelegate: ProviderDelegate! // to support callkit
@@ -55,25 +55,25 @@ import AVFoundation
var backgroundContextCall : Call?
@objc var backgroundContextCameraIsEnabled : Bool = false
-
+
fileprivate override init() {
providerDelegate = ProviderDelegate.shared
callController = CXCallController()
}
-
+
@objc static func instance() -> CallManager {
if (theCallManager == nil) {
theCallManager = CallManager()
}
return theCallManager!
}
-
-
+
+
@objc func setCore(core: OpaquePointer) {
lc = Core.getSwiftObject(cObject: core)
lc?.addDelegate(delegate: self)
}
-
+
@objc static func getAppData(call: OpaquePointer) -> CallAppData? {
let sCall = Call.getSwiftObject(cObject: call)
return getAppData(sCall: sCall)
@@ -85,7 +85,7 @@ import AVFoundation
}
return Unmanaged.fromOpaque(sCall.userData!).takeUnretainedValue()
}
-
+
@objc static func setAppData(call:OpaquePointer, appData: CallAppData) {
let sCall = Call.getSwiftObject(cObject: call)
setAppData(sCall: sCall, appData: appData)
@@ -101,12 +101,12 @@ import AVFoundation
sCall.userData = UnsafeMutableRawPointer(Unmanaged.passRetained(appData!).toOpaque())
}
}
-
+
@objc func findCall(callId: String?) -> OpaquePointer? {
let call = callByCallId(callId: callId)
return call?.getCobject
}
-
+
func callByCallId(callId: String?) -> Call? {
if (callId == nil) {
return nil
@@ -117,7 +117,7 @@ import AVFoundation
}
return nil
}
-
+
@objc func stopLinphoneCore() {
if (lc?.callsNb == 0) {
lc?.stopAsync()
@@ -136,11 +136,11 @@ import AVFoundation
}
@objc static func callKitEnabled() -> Bool {
- #if !targetEnvironment(simulator)
+#if !targetEnvironment(simulator)
if ConfigManager.instance().lpConfigBoolForKey(key: "use_callkit", section: "app") {
return true
}
- #endif
+#endif
return false
}
@@ -211,17 +211,17 @@ import AVFoundation
}
}
}
-
+
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, displayName: displayName)
}
-
+
@objc func acceptCall(call: OpaquePointer?, hasVideo:Bool) {
if (call == nil) {
Log.directLog(BCTBX_LOG_ERROR, text: "Can not accept null call!")
@@ -230,7 +230,7 @@ import AVFoundation
let call = Call.getSwiftObject(cObject: call!)
acceptCall(call: call, hasVideo: hasVideo)
}
-
+
func acceptCall(call: Call, hasVideo:Bool) {
do {
let callParams = try lc!.createCallParams(call: call)
@@ -242,7 +242,7 @@ import AVFoundation
}
callParams.lowBandwidthEnabled = low_bandwidth
}
-
+
//We set the record file name here because we can't do it after the call is started.
let address = call.callLog?.fromAddress
let writablePath = AppManager.recordingFilePathFromCall(address: address?.username ?? "")
@@ -268,14 +268,14 @@ import AVFoundation
Log.directLog(BCTBX_LOG_ERROR, text: "accept call failed \(error)")
}
}
-
+
// for outgoing call. There is not yet callId
@objc func startCall(addr: OpaquePointer?, isSas: Bool, isVideo: Bool, isConference: Bool = false) {
if (addr == nil) {
print("Can not start a call with null address!")
return
}
-
+
let sAddr = Address.getSwiftObject(cObject: addr!)
if (CallManager.callKitEnabled() && !CallManager.instance().nextCallIsTransfer && lc?.conference?.isIn != true) {
let uuid = UUID()
@@ -283,11 +283,11 @@ import AVFoundation
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, displayName: name, isVideo: isVideo, isConference:isConference)
providerDelegate.callInfos.updateValue(callInfo, forKey: uuid)
providerDelegate.uuids.updateValue(uuid, forKey: "")
-
+
setHeldOtherCalls(exceptCallid: "")
requestTransaction(transaction, action: "startCall")
}else {
@@ -297,30 +297,30 @@ import AVFoundation
func startCall(addr:String, isSas: Bool = false, isVideo: Bool, isConference: Bool = false) {
do {
- let address = try Factory.Instance.createAddress(addr: addr)
+ let address = try Factory.Instance.createAddress(addr: addr)
startCall(addr: address.getCobject,isSas: isSas, isVideo: isVideo, isConference:isConference)
} catch {
Log.e("[CallManager] unable to create address for a new outgoing call : \(addr) \(error) ")
}
}
-
+
func doCall(addr: Address, isSas: Bool, isVideo: Bool, isConference:Bool = false) throws {
let displayName = FastAddressBook.displayName(for: addr.getCobject)
-
+
let lcallParams = try CallManager.instance().lc!.createCallParams(call: nil)
if ConfigManager.instance().lpConfigBoolForKey(key: "edge_opt_preference") && AppManager.network() == .network_2g {
Log.directLog(BCTBX_LOG_MESSAGE, text: "Enabling low bandwidth mode")
lcallParams.lowBandwidthEnabled = true
}
-
+
if (displayName != nil) {
try addr.setDisplayname(newValue: displayName!)
}
-
+
if(ConfigManager.instance().lpConfigBoolForKey(key: "override_domain_with_default_one")) {
try addr.setDomain(newValue: ConfigManager.instance().lpConfigStringForKey(key: "domain", section: "assistant"))
}
-
+
if (CallManager.instance().nextCallIsTransfer) {
let call = CallManager.instance().lc!.currentCall
try call?.transferTo(referTo: addr)
@@ -362,7 +362,7 @@ import AVFoundation
}
}
}
-
+
@objc func groupCall() {
if (CallManager.callKitEnabled()) {
let calls = lc?.calls
@@ -371,29 +371,29 @@ import AVFoundation
}
let firstCall = calls!.first?.callLog?.callId ?? ""
let lastCall = (calls!.count > 1) ? calls!.last?.callLog?.callId ?? "" : ""
-
+
let currentUuid = CallManager.instance().providerDelegate.uuids["\(firstCall)"]
if (currentUuid == nil) {
Log.directLog(BCTBX_LOG_ERROR, text: "Can not find correspondant call to group.")
return
}
-
+
let newUuid = CallManager.instance().providerDelegate.uuids["\(lastCall)"]
let groupAction = CXSetGroupCallAction(call: currentUuid!, callUUIDToGroupWith: newUuid)
let transcation = CXTransaction(action: groupAction)
requestTransaction(transcation, action: "groupCall")
-
+
setResumeCalls()
} else {
try? lc?.addAllToConference()
}
}
-
+
@objc func removeAllCallInfos() {
providerDelegate.callInfos.removeAll()
providerDelegate.uuids.removeAll()
}
-
+
@objc func terminateCall(call: OpaquePointer?) {
if (call == nil) {
Log.directLog(BCTBX_LOG_ERROR, text: "Can not terminate null call!")
@@ -407,12 +407,12 @@ import AVFoundation
Log.directLog(BCTBX_LOG_ERROR, text: "Failed to terminate call failed because \(error)")
}
}
-
+
@objc func markCallAsDeclined(callId: String) {
if !CallManager.callKitEnabled() {
return
}
-
+
let uuid = providerDelegate.uuids["\(callId)"]
if (uuid == nil) {
Log.directLog(BCTBX_LOG_MESSAGE, text: "Mark call \(callId) as declined.")
@@ -426,7 +426,7 @@ import AVFoundation
providerDelegate.endCall(uuid: uuid!)
}
}
-
+
@objc func setHeld(call: OpaquePointer, hold: Bool) {
let sCall = Call.getSwiftObject(cObject: call)
if (!hold) {
@@ -437,13 +437,13 @@ import AVFoundation
func setHeld(call: Call, hold: Bool) {
- #if targetEnvironment(simulator)
+#if targetEnvironment(simulator)
if (hold) {
try?call.pause()
} else {
try?call.resume()
}
- #else
+#else
let callid = call.callLog?.callId ?? ""
let uuid = providerDelegate.uuids["\(callid)"]
if (uuid == nil) {
@@ -453,9 +453,9 @@ import AVFoundation
let setHeldAction = CXSetHeldCallAction(call: uuid!, onHold: hold)
let transaction = CXTransaction(action: setHeldAction)
requestTransaction(transaction, action: "setHeld")
- #endif
+#endif
}
-
+
@objc func setHeldOtherCalls(exceptCallid: String) {
for call in CallManager.instance().lc!.calls {
if (call.callLog?.callId != exceptCallid && call.state != .Paused && call.state != .Pausing && call.state != .PausedByRemote) {
@@ -463,7 +463,7 @@ import AVFoundation
}
}
}
-
+
func setResumeCalls() {
for call in CallManager.instance().lc!.calls {
if (call.state == .Paused || call.state == .Pausing || call.state == .PausedByRemote) {
@@ -471,7 +471,7 @@ import AVFoundation
}
}
}
-
+
@objc func performActionWhenCoreIsOn(action: @escaping ()->Void ) {
if (globalState == .On) {
action()
@@ -479,14 +479,14 @@ import AVFoundation
actionsToPerformOnceWhenCoreIsOn.append(action)
}
}
-
+
@objc func acceptVideo(call: OpaquePointer, confirm: Bool) {
let sCall = Call.getSwiftObject(cObject: call)
let params = try? lc?.createCallParams(call: sCall)
params?.videoEnabled = confirm
try? sCall.acceptUpdate(params: params)
}
-
+
func onGlobalStateChanged(core: Core, state: GlobalState, message: String) {
if (state == .On) {
actionsToPerformOnceWhenCoreIsOn.forEach {
@@ -496,7 +496,7 @@ import AVFoundation
}
globalState = state
}
-
+
func onRegistrationStateChanged(core: Core, proxyConfig: ProxyConfig, state: RegistrationState, message: String) {
if core.proxyConfigList.count == 1 && (state == .Failed || state == .Cleared){
// terminate callkit immediately when registration failed or cleared, supporting single proxy configuration
@@ -509,7 +509,7 @@ import AVFoundation
continue
}
}
-
+
CallManager.instance().providerDelegate.endCall(uuid: call.value)
}
CallManager.instance().endCallkit = true
@@ -536,7 +536,7 @@ import AVFoundation
return FastAddressBook.displayName(for: call.remoteAddress?.getCobject) ?? "Unknown"
}
}
-
+
func onCallStateChanged(core: Core, call: Call, state cstate: Call.State, message: String) {
let callLog = call.callLog
let callId = callLog?.callId
@@ -544,7 +544,7 @@ import AVFoundation
displayIncomingCall(call: call, handle: "Calling", hasVideo: false, callId: callId!, displayName: "Calling")
} else {
let video = (core.videoActivationPolicy?.automaticallyAccept ?? false) && (call.remoteParams?.videoEnabled ?? false)
-
+
if (call.userData == nil) {
let appData = CallAppData()
CallManager.setAppData(sCall: call, appData: appData)
@@ -555,11 +555,11 @@ import AVFoundation
ConferenceViewModel.shared.initConference(conference)
ConferenceViewModel.shared.configureConference(conference)
}
-
+
switch cstate {
- case .IncomingReceived:
- let addr = call.remoteAddress
- var displayName = incomingDisplayName(call: call)
+ case .IncomingReceived:
+ let addr = call.remoteAddress
+ var displayName = incomingDisplayName(call: call)
if call.replacedCall != nil {
endCallKitReplacedCall = false
@@ -572,174 +572,174 @@ import AVFoundation
CallManager.instance().providerDelegate.uuids.updateValue(uuid!, forKey: callInfo!.callId)
CallManager.instance().providerDelegate.updateCall(uuid: uuid!, handle: addr!.asStringUriOnly(), hasVideo: video, displayName: displayName)
} else if (CallManager.callKitEnabled()) {
- let isConference = isConferenceCall(call: call)
- let isEarlyConference = isConference && CallsViewModel.shared.currentCallData.value??.isConferenceCall.value != true // Conference info not be received yet.
- if (isEarlyConference) {
- CallsViewModel.shared.currentCallData.readCurrentAndObserve { _ in
- let uuid = CallManager.instance().providerDelegate.uuids["\(callId!)"]
- if (uuid != nil) {
- displayName = "\(VoipTexts.conference_incoming_title): \(CallsViewModel.shared.currentCallData.value??.remoteConferenceSubject.value ?? "") (\(CallsViewModel.shared.currentCallData.value??.conferenceParticipantsCountLabel.value ?? ""))"
- CallManager.instance().providerDelegate.updateCall(uuid: uuid!, handle: addr!.asStringUriOnly(), hasVideo: video, displayName: displayName)
- }
+ let isConference = isConferenceCall(call: call)
+ let isEarlyConference = isConference && CallsViewModel.shared.currentCallData.value??.isConferenceCall.value != true // Conference info not be received yet.
+ if (isEarlyConference) {
+ CallsViewModel.shared.currentCallData.readCurrentAndObserve { _ in
+ let uuid = CallManager.instance().providerDelegate.uuids["\(callId!)"]
+ if (uuid != nil) {
+ displayName = "\(VoipTexts.conference_incoming_title): \(CallsViewModel.shared.currentCallData.value??.remoteConferenceSubject.value ?? "") (\(CallsViewModel.shared.currentCallData.value??.conferenceParticipantsCountLabel.value ?? ""))"
+ CallManager.instance().providerDelegate.updateCall(uuid: uuid!, handle: addr!.asStringUriOnly(), hasVideo: video, displayName: displayName)
}
}
+ }
+
+ let uuid = CallManager.instance().providerDelegate.uuids["\(callId!)"]
+ if call.replacedCall == nil {
+ CallManager.uuidReplacedCall = callId
+ }
+
+ if (uuid != nil) {
+ // Tha app is now registered, updated the call already existed.
+ CallManager.instance().providerDelegate.updateCall(uuid: uuid!, handle: addr!.asStringUriOnly(), hasVideo: video, displayName: displayName)
+ } else {
+ 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 = displayName
+ content.sound = UNNotificationSound.init(named: UNNotificationSoundName.init("notes_of_the_optimistic.caf"))
+ content.categoryIdentifier = "call_cat"
+ content.userInfo = ["CallId" : callId!]
+ let req = UNNotificationRequest.init(identifier: "call_request", content: content, trigger: nil)
+ UNUserNotificationCenter.current().add(req, withCompletionHandler: nil)
+ }
+ break
+ case .StreamsRunning:
+ if (CallManager.callKitEnabled()) {
+ let uuid = CallManager.instance().providerDelegate.uuids["\(callId!)"]
+ if (uuid != nil) {
+ let callInfo = CallManager.instance().providerDelegate.callInfos[uuid!]
+ if (callInfo != nil && callInfo!.isOutgoing && !callInfo!.connected) {
+ Log.directLog(BCTBX_LOG_MESSAGE, text: "CallKit: outgoing call connected with uuid \(uuid!) and callId \(callId!)")
+ CallManager.instance().providerDelegate.reportOutgoingCallConnected(uuid: uuid!)
+ callInfo!.connected = true
+ CallManager.instance().providerDelegate.callInfos.updateValue(callInfo!, forKey: uuid!)
+ }
+ }
+ }
+
+ if (CallManager.instance().speakerBeforePause) {
+ CallManager.instance().speakerBeforePause = false
+ CallManager.instance().changeRouteToSpeaker()
+ }
+ actionToFulFill?.fulfill()
+ actionToFulFill = nil
+ break
+ case .Paused:
+ actionToFulFill?.fulfill()
+ actionToFulFill = nil
+ break
+ case .OutgoingInit,
+ .OutgoingProgress,
+ .OutgoingRinging,
+ .OutgoingEarlyMedia:
+ if (CallManager.callKitEnabled()) {
+ let uuid = CallManager.instance().providerDelegate.uuids[""]
+ if (uuid != nil) {
+ let callInfo = CallManager.instance().providerDelegate.callInfos[uuid!]
+ callInfo!.callId = callId!
+ CallManager.instance().providerDelegate.callInfos.updateValue(callInfo!, forKey: uuid!)
+ CallManager.instance().providerDelegate.uuids.removeValue(forKey: "")
+ CallManager.instance().providerDelegate.uuids.updateValue(uuid!, forKey: callId!)
+
+ Log.directLog(BCTBX_LOG_MESSAGE, text: "CallKit: outgoing call started connecting with uuid \(uuid!) and callId \(callId!)")
+ CallManager.instance().providerDelegate.reportOutgoingCallStartedConnecting(uuid: uuid!)
+ } else {
+ if CallManager.instance().isConferenceCall(call: call) {
+ let uuid = UUID()
+ let callInfo = CallInfo.newOutgoingCallInfo(addr: call.remoteAddress!, isSas: call.params?.mediaEncryption == .ZRTP, displayName: VoipTexts.conference_default_title, isVideo: call.params?.videoEnabled == true, isConference:true)
+ CallManager.instance().providerDelegate.callInfos.updateValue(callInfo, forKey: uuid)
+ CallManager.instance().providerDelegate.uuids.updateValue(uuid, forKey: "")
+ CallManager.instance().providerDelegate.reportOutgoingCallStartedConnecting(uuid: uuid)
+ Core.get().activateAudioSession(actived: true)
+ } else {
+ CallManager.instance().referedToCall = callId
+ }
+ }
+ }
+ break
+ case .End,
+ .Error:
+ var displayName = "Unknown"
+ if (call.dir == .Incoming) {
+ displayName = incomingDisplayName(call: call)
+ } else if let addr = call.remoteAddress, let contactName = FastAddressBook.displayName(for: addr.getCobject) {
+ displayName = contactName
+ }
+
+ UIDevice.current.isProximityMonitoringEnabled = false
+ if (CallManager.instance().lc!.callsNb == 0) {
+ CallManager.instance().changeRouteToDefault()
+ // disable this because I don't find anygood reason for it: _bluetoothAvailable = FALSE;
+ // furthermore it introduces a bug when calling multiple times since route may not be
+ // reconfigured between cause leading to bluetooth being disabled while it should not
+ //CallManager.instance().bluetoothEnabled = false
+ }
+
+ if UIApplication.shared.applicationState != .active && (callLog == nil || callLog?.status == .Missed || callLog?.status == .Aborted || callLog?.status == .EarlyAborted) {
+ // Configure the notification's payload.
+ let content = UNMutableNotificationContent()
+ content.title = NSString.localizedUserNotificationString(forKey: NSLocalizedString("Missed call", comment: ""), 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.
+ let center = UNUserNotificationCenter.current()
+ center.add(request) { (error : Error?) in
+ if error != nil {
+ Log.directLog(BCTBX_LOG_ERROR, text: "Error while adding notification request : \(error!.localizedDescription)")
+ }
+ }
+ }
+
+ if (CallManager.callKitEnabled()) {
+ var uuid = CallManager.instance().providerDelegate.uuids["\(callId!)"]
+ if (callId == CallManager.instance().referedToCall) {
+ // refered call ended before connecting
+ Log.directLog(BCTBX_LOG_MESSAGE, text: "Callkit: end refered to call : \(String(describing: CallManager.instance().referedToCall))")
+ CallManager.instance().referedFromCall = nil
+ CallManager.instance().referedToCall = nil
+ }
+ if uuid == nil {
+ // the call not yet connected
+ uuid = CallManager.instance().providerDelegate.uuids[""]
+ }
+ if (uuid != nil) {
+ if (callId == CallManager.instance().referedFromCall) {
+ Log.directLog(BCTBX_LOG_MESSAGE, text: "Callkit: end refered from call : \(String(describing: CallManager.instance().referedFromCall))")
+ CallManager.instance().referedFromCall = nil
+ let callInfo = CallManager.instance().providerDelegate.callInfos[uuid!]
+ callInfo!.callId = CallManager.instance().referedToCall ?? ""
+ CallManager.instance().providerDelegate.callInfos.updateValue(callInfo!, forKey: uuid!)
+ CallManager.instance().providerDelegate.uuids.removeValue(forKey: callId!)
+ CallManager.instance().providerDelegate.uuids.updateValue(uuid!, forKey: callInfo!.callId)
+ CallManager.instance().referedToCall = nil
+ break
+ }
+ if (endCallKitReplacedCall){
+ let transaction = CXTransaction(action:
+ CXEndCallAction(call: uuid!))
+ CallManager.instance().requestTransaction(transaction, action: "endCall")
+ }else{
+ endCallKitReplacedCall = true
+ }
- let uuid = CallManager.instance().providerDelegate.uuids["\(callId!)"]
- if call.replacedCall == nil {
- CallManager.uuidReplacedCall = callId
- }
-
- if (uuid != nil) {
- // Tha app is now registered, updated the call already existed.
- CallManager.instance().providerDelegate.updateCall(uuid: uuid!, handle: addr!.asStringUriOnly(), hasVideo: video, displayName: displayName)
- } else {
- 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 = displayName
- content.sound = UNNotificationSound.init(named: UNNotificationSoundName.init("notes_of_the_optimistic.caf"))
- content.categoryIdentifier = "call_cat"
- content.userInfo = ["CallId" : callId!]
- let req = UNNotificationRequest.init(identifier: "call_request", content: content, trigger: nil)
- UNUserNotificationCenter.current().add(req, withCompletionHandler: nil)
}
- break
- case .StreamsRunning:
- if (CallManager.callKitEnabled()) {
- let uuid = CallManager.instance().providerDelegate.uuids["\(callId!)"]
- if (uuid != nil) {
- let callInfo = CallManager.instance().providerDelegate.callInfos[uuid!]
- if (callInfo != nil && callInfo!.isOutgoing && !callInfo!.connected) {
- Log.directLog(BCTBX_LOG_MESSAGE, text: "CallKit: outgoing call connected with uuid \(uuid!) and callId \(callId!)")
- CallManager.instance().providerDelegate.reportOutgoingCallConnected(uuid: uuid!)
- callInfo!.connected = true
- CallManager.instance().providerDelegate.callInfos.updateValue(callInfo!, forKey: uuid!)
- }
- }
- }
-
- if (CallManager.instance().speakerBeforePause) {
- CallManager.instance().speakerBeforePause = false
- CallManager.instance().changeRouteToSpeaker()
- }
- actionToFulFill?.fulfill()
- actionToFulFill = nil
- break
- case .Paused:
- actionToFulFill?.fulfill()
- actionToFulFill = nil
+ }
+ break
+ case .Released:
+ CallManager.setAppData(sCall : call, appData : nil);
+ break
+ case .Referred:
+ CallManager.instance().referedFromCall = call.callLog?.callId
+ break
+ default:
break
- case .OutgoingInit,
- .OutgoingProgress,
- .OutgoingRinging,
- .OutgoingEarlyMedia:
- if (CallManager.callKitEnabled()) {
- let uuid = CallManager.instance().providerDelegate.uuids[""]
- if (uuid != nil) {
- let callInfo = CallManager.instance().providerDelegate.callInfos[uuid!]
- callInfo!.callId = callId!
- CallManager.instance().providerDelegate.callInfos.updateValue(callInfo!, forKey: uuid!)
- CallManager.instance().providerDelegate.uuids.removeValue(forKey: "")
- CallManager.instance().providerDelegate.uuids.updateValue(uuid!, forKey: callId!)
-
- Log.directLog(BCTBX_LOG_MESSAGE, text: "CallKit: outgoing call started connecting with uuid \(uuid!) and callId \(callId!)")
- CallManager.instance().providerDelegate.reportOutgoingCallStartedConnecting(uuid: uuid!)
- } else {
- if CallManager.instance().isConferenceCall(call: call) {
- let uuid = UUID()
- let callInfo = CallInfo.newOutgoingCallInfo(addr: call.remoteAddress!, isSas: call.params?.mediaEncryption == .ZRTP, displayName: VoipTexts.conference_default_title, isVideo: call.params?.videoEnabled == true, isConference:true)
- CallManager.instance().providerDelegate.callInfos.updateValue(callInfo, forKey: uuid)
- CallManager.instance().providerDelegate.uuids.updateValue(uuid, forKey: "")
- CallManager.instance().providerDelegate.reportOutgoingCallStartedConnecting(uuid: uuid)
- Core.get().activateAudioSession(actived: true)
- } else {
- CallManager.instance().referedToCall = callId
- }
- }
- }
- break
- case .End,
- .Error:
- var displayName = "Unknown"
- if (call.dir == .Incoming) {
- displayName = incomingDisplayName(call: call)
- } else if let addr = call.remoteAddress, let contactName = FastAddressBook.displayName(for: addr.getCobject) {
- displayName = contactName
- }
-
- UIDevice.current.isProximityMonitoringEnabled = false
- if (CallManager.instance().lc!.callsNb == 0) {
- CallManager.instance().changeRouteToDefault()
- // disable this because I don't find anygood reason for it: _bluetoothAvailable = FALSE;
- // furthermore it introduces a bug when calling multiple times since route may not be
- // reconfigured between cause leading to bluetooth being disabled while it should not
- //CallManager.instance().bluetoothEnabled = false
- }
-
- if UIApplication.shared.applicationState != .active && (callLog == nil || callLog?.status == .Missed || callLog?.status == .Aborted || callLog?.status == .EarlyAborted) {
- // Configure the notification's payload.
- let content = UNMutableNotificationContent()
- content.title = NSString.localizedUserNotificationString(forKey: NSLocalizedString("Missed call", comment: ""), 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.
- let center = UNUserNotificationCenter.current()
- center.add(request) { (error : Error?) in
- if error != nil {
- Log.directLog(BCTBX_LOG_ERROR, text: "Error while adding notification request : \(error!.localizedDescription)")
- }
- }
- }
-
- if (CallManager.callKitEnabled()) {
- var uuid = CallManager.instance().providerDelegate.uuids["\(callId!)"]
- if (callId == CallManager.instance().referedToCall) {
- // refered call ended before connecting
- Log.directLog(BCTBX_LOG_MESSAGE, text: "Callkit: end refered to call : \(String(describing: CallManager.instance().referedToCall))")
- CallManager.instance().referedFromCall = nil
- CallManager.instance().referedToCall = nil
- }
- if uuid == nil {
- // the call not yet connected
- uuid = CallManager.instance().providerDelegate.uuids[""]
- }
- if (uuid != nil) {
- if (callId == CallManager.instance().referedFromCall) {
- Log.directLog(BCTBX_LOG_MESSAGE, text: "Callkit: end refered from call : \(String(describing: CallManager.instance().referedFromCall))")
- CallManager.instance().referedFromCall = nil
- let callInfo = CallManager.instance().providerDelegate.callInfos[uuid!]
- callInfo!.callId = CallManager.instance().referedToCall ?? ""
- CallManager.instance().providerDelegate.callInfos.updateValue(callInfo!, forKey: uuid!)
- CallManager.instance().providerDelegate.uuids.removeValue(forKey: callId!)
- CallManager.instance().providerDelegate.uuids.updateValue(uuid!, forKey: callInfo!.callId)
- CallManager.instance().referedToCall = nil
- break
- }
- if (endCallKitReplacedCall){
- let transaction = CXTransaction(action:
- CXEndCallAction(call: uuid!))
- CallManager.instance().requestTransaction(transaction, action: "endCall")
- }else{
- endCallKitReplacedCall = true
- }
-
- }
- }
- break
- case .Released:
- CallManager.setAppData(sCall : call, appData : nil);
- break
- case .Referred:
- CallManager.instance().referedFromCall = call.callLog?.callId
- break
- default:
- break
}
-
+
let readyForRoutechange = CallManager.instance().callkitAudioSessionActivated == nil || (CallManager.instance().callkitAudioSessionActivated == true)
if (readyForRoutechange && (cstate == .IncomingReceived || cstate == .OutgoingInit || cstate == .Connected || cstate == .StreamsRunning)) {
if ((call.currentParams?.videoEnabled ?? false) && CallManager.instance().isReceiverEnabled() && call.conference == nil) {
@@ -757,7 +757,7 @@ import AVFoundation
AnyHashable("message"): message
])
}
-
+
// Audio messages
@objc func activateAudioSession() {
@@ -778,7 +778,7 @@ import AVFoundation
}
return speakerCard != nil ? speakerCard : earpieceCard
}
-
+
// Local Conference
@objc func startLocalConference() {
@@ -789,18 +789,18 @@ import AVFoundation
}
let firstCall = calls!.first?.callLog?.callId ?? ""
let lastCall = (calls!.count > 1) ? calls!.last?.callLog?.callId ?? "" : ""
-
+
let currentUuid = CallManager.instance().providerDelegate.uuids["\(firstCall)"]
if (currentUuid == nil) {
Log.directLog(BCTBX_LOG_ERROR, text: "Can not find correspondant call to group.")
return
}
-
+
let newUuid = CallManager.instance().providerDelegate.uuids["\(lastCall)"]
let groupAction = CXSetGroupCallAction(call: currentUuid!, callUUIDToGroupWith: newUuid)
let transcation = CXTransaction(action: groupAction)
requestTransaction(transcation, action: "groupCall")
-
+
setResumeCalls()
} else {
addAllToLocalConference()