| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- /*
- * Copyright @ 2018-present Atlassian Pty Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
- import AVKit
- import CallKit
- import Foundation
-
- internal final class JMCallKitEmitter: NSObject, CXProviderDelegate {
-
- private var listeners = Set<JMCallKitEventListenerWrapper>()
-
- internal override init() {}
-
- // MARK: - Add/remove listeners
-
- func addListener(_ listener: JMCallKitListener) {
- let wrapper = JMCallKitEventListenerWrapper(listener: listener)
- listeners.insert(wrapper)
- }
-
- func removeListener(_ listener: JMCallKitListener) {
- // XXX Constructing a new JMCallKitEventListenerWrapper instance in
- // order to remove the specified listener from listeners is (1) a bit
- // funny (though may make a statement about performance) and (2) not
- // really an option because the specified listener may already be
- // executing its dealloc (like RNCallKit).
- listeners.forEach {
- // 1. JMCallKitEventListenerWrapper weakly references
- // JMCallKitListener so it may be nice to clean
- // JMCallKitEventListenerWrapperinstances up if they've lost
- // their associated JMCallKitListener instances (e.g. for
- // example, because whoever did addListener forgot to
- // removeListener). Unfortunately, I don't know how to do it
- // because JMCallKitEventListenerWrapper is a struct.
- //
- // 2. XXX JMCallKitEventListenerWrapper implements the weird
- // equality by JMCallKitListener hash which (1) I don't
- // understand and (2) I don't know how to invoke without
- // duplicating.
- if ($0.hashValue == listener.hash) {
- listeners.remove($0)
- }
- }
- }
-
- // MARK: - CXProviderDelegate
-
- func providerDidReset(_ provider: CXProvider) {
- listeners.forEach { $0.listener?.providerDidReset?() }
- }
-
- func provider(_ provider: CXProvider, perform action: CXAnswerCallAction) {
- listeners.forEach {
- $0.listener?.performAnswerCall?(UUID: action.callUUID)
- }
-
- action.fulfill()
- }
-
- func provider(_ provider: CXProvider, perform action: CXEndCallAction) {
- listeners.forEach {
- $0.listener?.performEndCall?(UUID: action.callUUID)
- }
-
- action.fulfill()
- }
-
- func provider(_ provider: CXProvider, perform action: CXSetMutedCallAction) {
- listeners.forEach {
- $0.listener?.performSetMutedCall?(UUID: action.callUUID, isMuted: action.isMuted)
- }
-
- action.fulfill()
- }
-
- func provider(_ provider: CXProvider, perform action: CXStartCallAction) {
- listeners.forEach {
- $0.listener?.performStartCall?(UUID: action.callUUID,
- isVideo: action.isVideo)
- }
-
- action.fulfill()
- }
-
- func provider(_ provider: CXProvider,
- didActivate audioSession: AVAudioSession) {
- listeners.forEach {
- $0.listener?.providerDidActivateAudioSession?(session: audioSession)
- }
- }
-
- func provider(_ provider: CXProvider,
- didDeactivate audioSession: AVAudioSession) {
- listeners.forEach {
- $0.listener?.providerDidDeactivateAudioSession?(
- session: audioSession)
- }
- }
- }
-
- fileprivate struct JMCallKitEventListenerWrapper: Hashable {
-
- internal weak var listener: JMCallKitListener?
-
- public init(listener: JMCallKitListener) {
- self.listener = listener
- }
-
- public static func ==(lhs: JMCallKitEventListenerWrapper,
- rhs: JMCallKitEventListenerWrapper) -> Bool {
- // XXX We're aware that "[t]wo instances with equal hash values are not
- // necessarily equal to each other."
- return lhs.hashValue == rhs.hashValue
- }
-
- func hash(into hasher: inout Hasher) {
- hasher.combine(self.listener?.hash)
- }
- }
|