clear code

This commit is contained in:
Danmei Chen 2020-02-27 16:22:32 +01:00
parent d159b4cbf1
commit da4d9c7215
8 changed files with 243 additions and 175 deletions

63
Classes/AppManager.swift Normal file
View file

@ -0,0 +1,63 @@
/*
* Copyright (c) 2010-2019 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 <http://www.gnu.org/licenses/>.
*/
import Foundation
import CoreTelephony
enum NetworkType: Int {
case network_none = 0
case network_2g = 1
case network_3g = 2
case network_4g = 3
case network_lte = 4
case network_wifi = 5
}
@objc class AppManager: NSObject {
static func network() -> NetworkType {
let info = CTTelephonyNetworkInfo()
let currentRadio = info.currentRadioAccessTechnology
if (currentRadio == CTRadioAccessTechnologyEdge) {
return NetworkType.network_2g
} else if (currentRadio == CTRadioAccessTechnologyLTE) {
return NetworkType.network_4g
}
return NetworkType.network_3g
}
@objc static func recordingFilePathFromCall(address: String) -> String {
var filePath = "recording_"
filePath = filePath.appending(address.isEmpty ? address : "unknow")
let now = Date()
let dateFormat = DateFormatter()
dateFormat.dateFormat = "E-d-MMM-yyyy-HH-mm-ss"
let date = dateFormat.string(from: now)
filePath = filePath.appending("_\(date).mkv")
let paths = NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true)
var writablePath = paths[0]
writablePath = writablePath.appending("/\(filePath)")
Log.directLog(BCTBX_LOG_MESSAGE, text: "file path is \(writablePath)")
return writablePath
//file name is recording_contact-name_dayName-day-monthName-year-hour-minutes-seconds
//The recording prefix is used to identify recordings in the cache directory.
//We will use name_dayName-day-monthName-year to separate recordings by days, then hour-minutes-seconds to order them in each day.
}
}

View file

@ -23,37 +23,24 @@ import UserNotifications
import os
import CallKit
import AVFoundation
import CoreTelephony
enum NetworkType: Int {
case network_none = 0
case network_2g = 1
case network_3g = 2
case network_4g = 3
case network_lte = 4
case network_wifi = 5
}
@objc class CallAppData: NSObject {
@objc public var batteryWarningShown = false
@objc public var videoRequested = false /*set when user has requested for video*/
@objc var batteryWarningShown = false
@objc var videoRequested = false /*set when user has requested for video*/
}
@objc class CallManager: NSObject {
static var theCallManager: CallManager?
@objc static public var nextCallIsTransfer: Bool = false
let providerDelegate: ProviderDelegate!
let callController: CXCallController!
let manager: CoreManager!
let applicationKey = "app"
var callAppDatas: [String : CallAppData] = [:]
var lc: Core?
@objc var speakerBeforePause : Bool = false
@objc var speakerEnabled : Bool = false
@objc var bluetoothEnabled : Bool = false
@objc var nextCallIsTransfer: Bool = false
var callAppDatas: [String : CallAppData] = [:]
var lc: Core?
var config: Config?
fileprivate override init() {
providerDelegate = ProviderDelegate()
@ -68,6 +55,11 @@ enum NetworkType: Int {
return theCallManager!
}
@objc func setCore(core: OpaquePointer) {
lc = Core.getSwiftObject(cObject: core)
lc?.addDelegate(delegate: manager)
}
@objc func getAppData (callId : String) -> CallAppData? {
return CallManager.instance().callAppDatas["\(callId)"]
}
@ -76,12 +68,6 @@ enum NetworkType: Int {
CallManager.instance().callAppDatas.updateValue(appData, forKey: callId)
}
@objc func configCallManager(core: OpaquePointer, db:OpaquePointer) {
lc = Core.getSwiftObject(cObject: core)
lc?.addDelegate(delegate: manager)
config = Config.getSwiftObject(cObject: db)
}
@objc func findCall(callId: String?) -> OpaquePointer? {
let call = callByCallId(callId: callId)
return call?.getCobject
@ -100,24 +86,13 @@ enum NetworkType: Int {
@objc static func callKitEnabled() -> Bool {
#if !targetEnvironment(simulator)
if CallManager.instance().lpConfigBoolForKey(key: "use_callkit", section: "app") {
if ConfigManager.instance().lpConfigBoolForKey(key: "use_callkit", section: "app") {
return true
}
#endif
return false
}
static func network() -> NetworkType {
let info = CTTelephonyNetworkInfo()
let currentRadio = info.currentRadioAccessTechnology
if (currentRadio == CTRadioAccessTechnologyEdge) {
return NetworkType.network_2g
} else if (currentRadio == CTRadioAccessTechnologyLTE) {
return NetworkType.network_4g
}
return NetworkType.network_3g
}
@objc func allowSpeaker() -> Bool {
if (UIDevice.current.userInterfaceIdiom == .pad) {
// For now, ipad support only speaker.
@ -150,26 +125,6 @@ enum NetworkType: Int {
Log.directLog(BCTBX_LOG_ERROR, text: "Failed to change audio route: err \(error)")
}
}
@objc static func recordingFilePathFromCall(address: String) -> String {
var filePath = "recording_"
filePath = filePath.appending(address.isEmpty ? address : "unknow")
let now = Date()
let dateFormat = DateFormatter()
dateFormat.dateFormat = "E-d-MMM-yyyy-HH-mm-ss"
let date = dateFormat.string(from: now)
filePath = filePath.appending("_\(date).mkv")
let paths = NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true)
var writablePath = paths[0]
writablePath = writablePath.appending("/\(filePath)")
Log.directLog(BCTBX_LOG_MESSAGE, text: "file path is \(writablePath)")
return writablePath
//file name is recording_contact-name_dayName-day-monthName-year-hour-minutes-seconds
//The recording prefix is used to identify recordings in the cache directory.
//We will use name_dayName-day-monthName-year to separate recordings by days, then hour-minutes-seconds to order them in each day.
}
func requestTransaction(_ transaction: CXTransaction, action: String) {
callController.request(transaction) { error in
@ -208,8 +163,8 @@ enum NetworkType: Int {
do {
let callParams = try lc!.createCallParams(call: call)
callParams.videoEnabled = hasVideo
if (lpConfigBoolForKey(key: "edge_opt_preference")) {
let low_bandwidth = (CallManager.network() == .network_2g)
if (ConfigManager.instance().lpConfigBoolForKey(key: "edge_opt_preference")) {
let low_bandwidth = (AppManager.network() == .network_2g)
if (low_bandwidth) {
Log.directLog(BCTBX_LOG_MESSAGE, text: "Low bandwidth mode")
}
@ -218,7 +173,7 @@ enum NetworkType: Int {
//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 = CallManager.recordingFilePathFromCall(address: address?.username ?? "")
let writablePath = AppManager.recordingFilePathFromCall(address: address?.username ?? "")
Log.directLog(BCTBX_LOG_MESSAGE, text: "Record file path: \(String(describing: writablePath))")
callParams.recordFile = writablePath
@ -257,7 +212,7 @@ enum NetworkType: Int {
let displayName = FastAddressBook.displayName(for: addr.getCobject)
let lcallParams = try CallManager.instance().lc!.createCallParams(call: nil)
if CallManager.instance().lpConfigBoolForKey(key: "edge_opt_preference") && CallManager.network() == .network_2g {
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
}
@ -266,17 +221,17 @@ enum NetworkType: Int {
try addr.setDisplayname(newValue: displayName!)
}
if(CallManager.instance().lpConfigBoolForKey(key: "override_domain_with_default_one")) {
try addr.setDomain(newValue: CallManager.instance().lpConfigStringForKey(key: "domain", section: "assistant"))
if(ConfigManager.instance().lpConfigBoolForKey(key: "override_domain_with_default_one")) {
try addr.setDomain(newValue: ConfigManager.instance().lpConfigStringForKey(key: "domain", section: "assistant"))
}
if (CallManager.nextCallIsTransfer) {
if (CallManager.instance().nextCallIsTransfer) {
let call = CallManager.instance().lc!.currentCall
try call?.transfer(referTo: addr.asString())
CallManager.nextCallIsTransfer = false
CallManager.instance().nextCallIsTransfer = false
} else {
//We set the record file name here because we can't do it after the call is started.
let writablePath = CallManager.recordingFilePathFromCall(address: addr.username )
let writablePath = AppManager.recordingFilePathFromCall(address: addr.username )
Log.directLog(BCTBX_LOG_DEBUG, text: "record file path: \(writablePath)")
lcallParams.recordFile = writablePath
if (isSas) {
@ -343,93 +298,6 @@ enum NetworkType: Int {
Log.directLog(BCTBX_LOG_WARNING, text: "CallKit: Unable to config audio session because : \(error)")
}
}
//pragma mark - LPConfig Functions
@objc func lpConfigSetString(value:String, key:String, section:String) {
if (!key.isEmpty) {
config?.setString(section: section, key: key, value: value)
}
}
@objc func lpConfigSetString(value:String, key:String) {
lpConfigSetString(value: value, key: key, section: applicationKey)
}
@objc func lpConfigStringForKey(key:String, section:String, defaultValue:String) -> String {
if (key.isEmpty) {
return defaultValue
}
return config?.getString(section: section, key: key, defaultString: "") ?? defaultValue
}
@objc func lpConfigStringForKey(key:String, section:String) -> String {
return lpConfigStringForKey(key: key, section: section, defaultValue: "")
}
@objc func lpConfigStringForKey(key:String, defaultValue:String) -> String {
return lpConfigStringForKey(key: key, section: applicationKey, defaultValue: defaultValue)
}
@objc func lpConfigStringForKey(key:String) -> String {
return lpConfigStringForKey(key: key, defaultValue: "")
}
@objc func lpConfigSetInt(value:Int, key:String, section:String) {
if(!key.isEmpty) {
config?.setInt(section: section, key: key, value: value)
}
}
@objc func lpConfigSetInt(value:Int, key:String) {
lpConfigSetInt(value: value, key: key, section: applicationKey)
}
@objc func lpConfigIntForKey(key:String, section:String, defaultValue:Int) -> Int {
if (key.isEmpty) {
return defaultValue
}
return config?.getInt(section: section, key: key, defaultValue: defaultValue) ?? defaultValue
}
@objc func lpConfigIntForKey(key:String, section:String) -> Int {
return lpConfigIntForKey(key: key, section: section, defaultValue: -1)
}
@objc func lpConfigIntForKey(key:String, defaultValue:Int) -> Int {
return lpConfigIntForKey(key: key, section: applicationKey, defaultValue: defaultValue)
}
@objc func lpConfigIntForKey(key:String) -> Int {
return lpConfigIntForKey(key: key, defaultValue: -1)
}
@objc func lpConfigSetBool(value:Bool, key:String, section:String) {
lpConfigSetInt(value: value ? 1:0, key: key, section: section)
}
@objc func lpConfigSetBool(value:Bool, key:String) {
lpConfigSetBool(value: value, key: key, section: applicationKey)
}
@objc func lpConfigBoolForKey(key:String, section:String, defaultValue:Bool) -> Bool {
if (key.isEmpty) {
return defaultValue
}
let val = lpConfigIntForKey(key: key, section: section, defaultValue: -1)
return (val != -1) ? (val == 1) : defaultValue
}
@objc func lpConfigBoolForKey(key:String, section:String) -> Bool {
return lpConfigBoolForKey(key: key, section: section, defaultValue: false)
}
@objc func lpConfigBoolForKey(key:String, defaultValue:Bool) -> Bool {
return lpConfigBoolForKey(key: key, section: applicationKey, defaultValue: defaultValue)
}
@objc func lpConfigBoolForKey(key:String) -> Bool {
return lpConfigBoolForKey(key: key, defaultValue: false)
}
}
class CoreManager: CoreDelegate {
@ -457,8 +325,12 @@ class CoreManager: CoreDelegate {
// Tha app is now registered, updated the call already existed.
CallManager.instance().providerDelegate.updateCall(uuid: uuid!, handle: address, hasVideo: video)
let callInfo = CallManager.instance().providerDelegate.callInfos[uuid!]
let connected = callInfo?.connected ?? false
if (connected) {
let accepted = callInfo?.accepted ?? false
let declined = callInfo?.declined ?? false
if (declined) {
// The call is already declined.
try? call.decline(reason: Reason.Unknown)
} else if (accepted) {
// The call is already answered.
CallManager.instance().acceptCall(call: call, hasVideo: video)
}

View file

@ -139,7 +139,7 @@ static UICompositeViewDescription *compositeDescription = nil;
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
_waitView.hidden = TRUE;
CallManager.nextCallIsTransfer = FALSE;
CallManager.instance.nextCallIsTransfer = FALSE;
callRecording = FALSE;
_recordButtonOnView.hidden = TRUE;
@ -844,7 +844,7 @@ static void hideSpinner(LinphoneCall *call, void *user_data) {
[self hideOptions:TRUE animated:TRUE];
DialerView *view = VIEW(DialerView);
[view setAddress:@""];
CallManager.nextCallIsTransfer = TRUE;
CallManager.instance.nextCallIsTransfer = TRUE;
[PhoneMainView.instance changeCurrentView:view.compositeViewDescription];
}
@ -852,7 +852,7 @@ static void hideSpinner(LinphoneCall *call, void *user_data) {
[self hideOptions:TRUE animated:TRUE];
DialerView *view = VIEW(DialerView);
[view setAddress:@""];
CallManager.nextCallIsTransfer = FALSE;
CallManager.instance.nextCallIsTransfer = FALSE;
[PhoneMainView.instance changeCurrentView:view.compositeViewDescription];
}

125
Classes/ConfigManager.swift Normal file
View file

@ -0,0 +1,125 @@
/*
* Copyright (c) 2010-2019 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 <http://www.gnu.org/licenses/>.
*/
import Foundation
import linphonesw
@objc class ConfigManager: NSObject {
static var theConfigManager: ConfigManager?
var config: Config?
let applicationKey = "app"
@objc static func instance() -> ConfigManager {
if (theConfigManager == nil) {
theConfigManager = ConfigManager()
}
return theConfigManager!
}
@objc func setDb(db:OpaquePointer) {
config = Config.getSwiftObject(cObject: db)
}
//pragma mark - LPConfig Functions
@objc func lpConfigSetString(value:String, key:String, section:String) {
if (!key.isEmpty) {
config?.setString(section: section, key: key, value: value)
}
}
@objc func lpConfigSetString(value:String, key:String) {
lpConfigSetString(value: value, key: key, section: applicationKey)
}
@objc func lpConfigStringForKey(key:String, section:String, defaultValue:String) -> String {
if (key.isEmpty) {
return defaultValue
}
return config?.getString(section: section, key: key, defaultString: "") ?? defaultValue
}
@objc func lpConfigStringForKey(key:String, section:String) -> String {
return lpConfigStringForKey(key: key, section: section, defaultValue: "")
}
@objc func lpConfigStringForKey(key:String, defaultValue:String) -> String {
return lpConfigStringForKey(key: key, section: applicationKey, defaultValue: defaultValue)
}
@objc func lpConfigStringForKey(key:String) -> String {
return lpConfigStringForKey(key: key, defaultValue: "")
}
@objc func lpConfigSetInt(value:Int, key:String, section:String) {
if(!key.isEmpty) {
config?.setInt(section: section, key: key, value: value)
}
}
@objc func lpConfigSetInt(value:Int, key:String) {
lpConfigSetInt(value: value, key: key, section: applicationKey)
}
@objc func lpConfigIntForKey(key:String, section:String, defaultValue:Int) -> Int {
if (key.isEmpty) {
return defaultValue
}
return config?.getInt(section: section, key: key, defaultValue: defaultValue) ?? defaultValue
}
@objc func lpConfigIntForKey(key:String, section:String) -> Int {
return lpConfigIntForKey(key: key, section: section, defaultValue: -1)
}
@objc func lpConfigIntForKey(key:String, defaultValue:Int) -> Int {
return lpConfigIntForKey(key: key, section: applicationKey, defaultValue: defaultValue)
}
@objc func lpConfigIntForKey(key:String) -> Int {
return lpConfigIntForKey(key: key, defaultValue: -1)
}
@objc func lpConfigSetBool(value:Bool, key:String, section:String) {
lpConfigSetInt(value: value ? 1:0, key: key, section: section)
}
@objc func lpConfigSetBool(value:Bool, key:String) {
lpConfigSetBool(value: value, key: key, section: applicationKey)
}
@objc func lpConfigBoolForKey(key:String, section:String, defaultValue:Bool) -> Bool {
if (key.isEmpty) {
return defaultValue
}
let val = lpConfigIntForKey(key: key, section: section, defaultValue: -1)
return (val != -1) ? (val == 1) : defaultValue
}
@objc func lpConfigBoolForKey(key:String, section:String) -> Bool {
return lpConfigBoolForKey(key: key, section: section, defaultValue: false)
}
@objc func lpConfigBoolForKey(key:String, defaultValue:Bool) -> Bool {
return lpConfigBoolForKey(key: key, section: applicationKey, defaultValue: defaultValue)
}
@objc func lpConfigBoolForKey(key:String) -> Bool {
return lpConfigBoolForKey(key: key, defaultValue: false)
}
}

View file

@ -1445,8 +1445,8 @@ void popup_link_account_cb(LinphoneAccountCreator *creator, LinphoneAccountCreat
theLinphoneCore = linphone_factory_create_core_with_config_3(factory, _configDb, NULL);
linphone_core_add_callbacks(theLinphoneCore, cbs);
// Add call changed callback by swift
[CallManager.instance configCallManagerWithCore:theLinphoneCore db:_configDb];
[CallManager.instance setCoreWithCore:theLinphoneCore];
[ConfigManager.instance setDbWithDb:_configDb];
linphone_core_start(theLinphoneCore);

View file

@ -102,7 +102,7 @@
[self setImage:[UIImage imageNamed:@"call_audio_start_disabled.png"] forState:UIControlStateDisabled];
}
if (CallManager.nextCallIsTransfer) {
if (CallManager.instance.nextCallIsTransfer) {
[self setImage:[UIImage imageNamed:@"call_transfer_default.png"] forState:UIControlStateNormal];
[self setImage:[UIImage imageNamed:@"call_transfer_disabled.png"] forState:UIControlStateDisabled];
} else if (linphone_core_get_calls_nb(LC) > 0) {

View file

@ -24,12 +24,14 @@ import linphonesw
import AVFoundation
import os
class CallInfo: NSObject {
@objc class CallInfo: NSObject {
var callId: String = ""
var connected = false
var accepted = false
var toAddr: Address?
var isOutgoing = false
var sasEnabled = false
var declined = false
static func newIncomingCallInfo(callId: String) -> CallInfo {
let callInfo = CallInfo()
@ -48,17 +50,12 @@ class CallInfo: NSObject {
class ProviderDelegate: NSObject {
private let provider: CXProvider
private let callController: CXCallController
var uuids: [String : UUID] = [:]
var callInfos: [UUID : CallInfo] = [:]
override init() {
provider = CXProvider(configuration: ProviderDelegate.providerConfiguration)
callController = CXCallController()
super.init()
provider.setDelegate(self, queue: nil)
}
@ -83,16 +80,22 @@ class ProviderDelegate: NSObject {
update.remoteHandle = CXHandle(type:.generic, value: handle)
update.hasVideo = hasVideo
let callId = callInfos[uuid]?.callId
let callInfo = callInfos[uuid]
let callId = callInfo?.callId
Log.directLog(BCTBX_LOG_MESSAGE, text: "CallKit: report new incoming call with call-id: [\(String(describing: callId))] and UUID: [\(uuid.description)]")
provider.reportNewIncomingCall(with: uuid, update: update) { error in
if error == nil {
} else {
Log.directLog(BCTBX_LOG_ERROR, text: "CallKit: cannot complete incoming call with call-id: [\(String(describing: callId))] and UUID: [\(uuid.description)] from [\(handle)] caused by [\(error!.localizedDescription)]")
if (call == nil) {
callInfo?.declined = true
self.callInfos.updateValue(callInfo!, forKey: uuid)
return
}
let code = (error as NSError?)?.code
if code == CXErrorCodeIncomingCallError.filteredByBlockList.rawValue || code == CXErrorCodeIncomingCallError.filteredByDoNotDisturb.rawValue {
try? call?.decline(reason: Reason.Busy)
} else {
} else {
try? call?.decline(reason: Reason.Unknown)
}
}
@ -103,7 +106,6 @@ class ProviderDelegate: NSObject {
let update = CXCallUpdate()
update.remoteHandle = CXHandle(type:.generic, value:handle)
update.hasVideo = hasVideo
provider.reportCall(with:uuid, updated:update);
}
@ -147,10 +149,10 @@ extension ProviderDelegate: CXProviderDelegate {
Log.directLog(BCTBX_LOG_MESSAGE, text: "CallKit: answer call with call-id: \(String(describing: callId)) and UUID: \(uuid.description).")
let call = CallManager.instance().callByCallId(callId: callId)
if (call == nil) {
// The application is not yet registered, mark the call as connected. The audio session must be configured here.
if (call == nil || call?.state != Call.State.IncomingReceived) {
// The application is not yet registered or the call is not yet received, mark the call as accepted. The audio session must be configured here.
CallManager.configAudioSession(audioSession: AVAudioSession.sharedInstance())
callInfo?.connected = true
callInfo?.accepted = true
callInfos.updateValue(callInfo!, forKey: uuid)
} else {
CallManager.instance().acceptCall(call: call!, hasVideo: call!.params?.videoEnabled ?? false)
@ -211,7 +213,6 @@ extension ProviderDelegate: CXProviderDelegate {
let uuid = action.callUUID
let callId = callInfos[uuid]?.callId
Log.directLog(BCTBX_LOG_MESSAGE, text: "CallKit: Call muted with call-id: \(String(describing: callId)) an UUID: \(uuid.description).")
CallManager.instance().lc!.micEnabled = !CallManager.instance().lc!.micEnabled
action.fulfill()
}
@ -220,7 +221,6 @@ extension ProviderDelegate: CXProviderDelegate {
let uuid = action.callUUID
let callId = callInfos[uuid]?.callId
Log.directLog(BCTBX_LOG_MESSAGE, text: "CallKit: Call send dtmf with call-id: \(String(describing: callId)) an UUID: \(uuid.description).")
let call = CallManager.instance().callByCallId(callId: callId)
if (call != nil) {
let digit = (action.digits.cString(using: String.Encoding.utf8)?[0])!

View file

@ -82,6 +82,8 @@
5EEE8F9B20C80C23006E4176 /* NotificationCenter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5EF0C33820C806A5005081B0 /* NotificationCenter.framework */; };
5EEE8F9F20C80C23006E4176 /* TodayViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EEE8F9E20C80C23006E4176 /* TodayViewController.m */; };
5EEE8FA220C80C23006E4176 /* MainInterface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5EEE8FA020C80C23006E4176 /* MainInterface.storyboard */; };
6134812D2406CECC00695B41 /* ConfigManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6134812C2406CECC00695B41 /* ConfigManager.swift */; };
6134812F2407B35200695B41 /* AppManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6134812E2407B35200695B41 /* AppManager.swift */; };
614C087823D1A35F00217F80 /* ProviderDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 614C087723D1A35F00217F80 /* ProviderDelegate.swift */; };
614C087A23D1A37400217F80 /* CallManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 614C087923D1A37400217F80 /* CallManager.swift */; };
614D09CE21E74D5400C43EDF /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 614D09CD21E74D5400C43EDF /* GoogleService-Info.plist */; };
@ -962,6 +964,8 @@
5EEE8FB320C81334006E4176 /* latestCallsWidget.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = latestCallsWidget.entitlements; sourceTree = "<group>"; };
5EF0C33820C806A5005081B0 /* NotificationCenter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = NotificationCenter.framework; path = System/Library/Frameworks/NotificationCenter.framework; sourceTree = SDKROOT; };
6130C85B22BBB493009CC79C /* LaunchScreen.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LaunchScreen.h; sourceTree = "<group>"; };
6134812C2406CECC00695B41 /* ConfigManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfigManager.swift; sourceTree = "<group>"; };
6134812E2407B35200695B41 /* AppManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppManager.swift; sourceTree = "<group>"; };
614C087623D1A35E00217F80 /* linphone-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "linphone-Bridging-Header.h"; sourceTree = "<group>"; };
614C087723D1A35F00217F80 /* ProviderDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProviderDelegate.swift; sourceTree = "<group>"; };
614C087923D1A37400217F80 /* CallManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CallManager.swift; sourceTree = "<group>"; };
@ -2183,6 +2187,8 @@
34216F3F1547EBCD00EA9777 /* VideoZoomHandler.m */,
614C087723D1A35F00217F80 /* ProviderDelegate.swift */,
614C087923D1A37400217F80 /* CallManager.swift */,
6134812C2406CECC00695B41 /* ConfigManager.swift */,
6134812E2407B35200695B41 /* AppManager.swift */,
614C087623D1A35E00217F80 /* linphone-Bridging-Header.h */,
);
path = Classes;
@ -4404,6 +4410,7 @@
633671611BCBAAD200BFCBDE /* ChatConversationCreateView.m in Sources */,
634610061B61330300548952 /* UILabel+Boldify.m in Sources */,
2248E90E12F7E4CF00220D9C /* UIDigitButton.m in Sources */,
6134812F2407B35200695B41 /* AppManager.swift in Sources */,
633756391B67BAF400E21BAD /* SideMenuTableView.m in Sources */,
2214EB7A12F846B1002A5394 /* UICallButton.m in Sources */,
6352A5751BE0D4B800594C1C /* CallSideMenuView.m in Sources */,
@ -4413,6 +4420,7 @@
8C9C5E111F83BD97006987FA /* UIChatCreateCollectionViewCell.m in Sources */,
22968A5F12F875C600588287 /* UISpeakerButton.m in Sources */,
63701DDF1BA32039006A9AE3 /* UIConfirmationDialog.m in Sources */,
6134812D2406CECC00695B41 /* ConfigManager.swift in Sources */,
22C755601317E59C007BC101 /* UIBluetoothButton.m in Sources */,
22AA8B0113D83F6300B30535 /* UICamSwitch.m in Sources */,
63B8D6A21BCBF43100C12B09 /* UIChatCreateCell.m in Sources */,