"Fossies" - the Fresh Open Source Software Archive

Member "jitsi-meet-4423/ios/sdk/src/callkit/JMCallKitProxy.swift" (22 Sep 2020, 7028 Bytes) of package /linux/misc/jitsi-meet-4423.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Swift source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 /*
    2  * Copyright @ 2019-present 8x8, Inc.
    3  * Copyright @ 2018-2019 Atlassian Pty Ltd
    4  *
    5  * Licensed under the Apache License, Version 2.0 (the "License");
    6  * you may not use this file except in compliance with the License.
    7  * You may obtain a copy of the License at
    8  *
    9  *     http://www.apache.org/licenses/LICENSE-2.0
   10  *
   11  * Unless required by applicable law or agreed to in writing, software
   12  * distributed under the License is distributed on an "AS IS" BASIS,
   13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   14  * See the License for the specific language governing permissions and
   15  * limitations under the License.
   16  */
   17 
   18 import CallKit
   19 import Foundation
   20 
   21 /// JitsiMeet CallKit proxy
   22 // NOTE: The methods this class exposes are meant to be called in the UI thread.
   23 // All delegate methods called by JMCallKitEmitter will be called in the UI thread.
   24 @objc public final class JMCallKitProxy: NSObject {
   25 
   26     private override init() {}
   27 
   28     // MARK: - CallKit proxy
   29 
   30     private static var provider: CXProvider = {
   31         let configuration = CXProviderConfiguration(localizedName: "")
   32         return CXProvider(configuration: configuration)
   33     }()
   34 
   35     private static var providerConfiguration: CXProviderConfiguration? {
   36         didSet {
   37             guard let configuration = providerConfiguration else { return }
   38             provider.configuration = configuration
   39             provider.setDelegate(emitter, queue: nil)
   40         }
   41     }
   42 
   43     private static let callController: CXCallController = {
   44         return CXCallController()
   45     }()
   46 
   47     private static let emitter: JMCallKitEmitter = {
   48         return JMCallKitEmitter()
   49     }()
   50 
   51     /// Enables the proxy in between CallKit and the consumers of the SDK.
   52     /// Defaults to enabled, set to false when you don't want to use CallKit.
   53     @objc public static var enabled: Bool = true {
   54         didSet {
   55             provider.invalidate()
   56             if enabled {
   57                 guard isProviderConfigured() else  { return; }
   58                 provider = CXProvider(configuration: providerConfiguration!)
   59                 provider.setDelegate(emitter, queue: nil)
   60             } else {
   61                 provider.setDelegate(nil, queue: nil)
   62             }
   63         }
   64     }
   65 
   66     @objc public static func configureProvider(localizedName: String,
   67                                                ringtoneSound: String?,
   68                                                iconTemplateImageData: Data?) {
   69         guard enabled else { return }
   70 
   71         let configuration = CXProviderConfiguration(localizedName: localizedName)
   72         configuration.iconTemplateImageData = iconTemplateImageData
   73         configuration.maximumCallGroups = 1
   74         configuration.maximumCallsPerCallGroup = 1
   75         configuration.ringtoneSound = ringtoneSound
   76         configuration.supportedHandleTypes = [CXHandle.HandleType.generic]
   77         configuration.supportsVideo = true
   78 
   79         providerConfiguration = configuration
   80     }
   81 
   82     @objc public static func isProviderConfigured() -> Bool {
   83         return providerConfiguration != nil
   84     }
   85 
   86     @objc public static func addListener(_ listener: JMCallKitListener) {
   87         emitter.addListener(listener)
   88     }
   89 
   90     @objc public static func removeListener(_ listener: JMCallKitListener) {
   91         emitter.removeListener(listener)
   92     }
   93 
   94     @objc public static func hasActiveCallForUUID(_ callUUID: String) -> Bool {
   95         let activeCallForUUID = callController.callObserver.calls.first {
   96             $0.uuid == UUID(uuidString: callUUID)
   97         }
   98         guard activeCallForUUID != nil else { return false }
   99         return true
  100     }
  101 
  102     @objc public static func reportNewIncomingCall(
  103             UUID: UUID,
  104             handle: String?,
  105             displayName: String?,
  106             hasVideo: Bool,
  107             completion: @escaping (Error?) -> Void) {
  108         guard enabled else { return }
  109 
  110         let callUpdate = makeCXUpdate(handle: handle,
  111                                       displayName: displayName,
  112                                       hasVideo: hasVideo)
  113         provider.reportNewIncomingCall(with: UUID,
  114                                        update: callUpdate,
  115                                        completion: completion)
  116     }
  117 
  118     @objc public static func reportCallUpdate(with UUID: UUID,
  119                                               handle: String?,
  120                                               displayName: String?,
  121                                               hasVideo: Bool) {
  122         guard enabled else { return }
  123 
  124         let callUpdate = makeCXUpdate(handle: handle,
  125                                       displayName: displayName,
  126                                       hasVideo: hasVideo)
  127         provider.reportCall(with: UUID, updated: callUpdate)
  128     }
  129 
  130     @objc public static func reportCall(
  131             with UUID: UUID,
  132             endedAt dateEnded: Date?,
  133             reason endedReason: CXCallEndedReason) {
  134         guard enabled else { return }
  135 
  136         provider.reportCall(with: UUID,
  137                             endedAt: dateEnded,
  138                             reason: endedReason)
  139     }
  140 
  141     @objc public static func reportOutgoingCall(
  142             with UUID: UUID,
  143             startedConnectingAt dateStartedConnecting: Date?) {
  144         guard enabled else { return }
  145 
  146         provider.reportOutgoingCall(with: UUID,
  147                                     startedConnectingAt: dateStartedConnecting)
  148     }
  149 
  150     @objc public static func reportOutgoingCall(
  151             with UUID: UUID,
  152             connectedAt dateConnected: Date?) {
  153         guard enabled else { return }
  154 
  155         provider.reportOutgoingCall(with: UUID, connectedAt: dateConnected)
  156     }
  157 
  158     @objc public static func request(
  159             _ transaction: CXTransaction,
  160             completion: @escaping (Error?) -> Swift.Void) {
  161         guard enabled else { return }
  162 
  163         // XXX keep track of muted actions to avoid "ping-pong"ing. See
  164         // JMCallKitEmitter for details on the CXSetMutedCallAction handling.
  165         for action in transaction.actions {
  166             if (action as? CXSetMutedCallAction) != nil {
  167                 emitter.addMuteAction(action.uuid)
  168             }
  169         }
  170 
  171         callController.request(transaction, completion: completion)
  172     }
  173 
  174     // MARK: - Callkit Proxy helpers
  175 
  176     private static func makeCXUpdate(handle: String?,
  177                                      displayName: String?,
  178                                      hasVideo: Bool) -> CXCallUpdate {
  179         let update = CXCallUpdate()
  180         update.supportsDTMF = false
  181         update.supportsHolding = false
  182         update.supportsGrouping = false
  183         update.supportsUngrouping = false
  184         update.hasVideo = hasVideo
  185 
  186         if let handle = handle {
  187             update.remoteHandle = CXHandle(type: .generic,
  188                                            value: handle)
  189         }
  190 
  191         if let displayName = displayName {
  192             update.localizedCallerName = displayName
  193         }
  194 
  195         return update
  196     }
  197 }
  198