You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

JMCallKitEmitter.swift 4.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. /*
  2. * Copyright @ 2018-present Atlassian Pty Ltd
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. import AVKit
  17. import CallKit
  18. import Foundation
  19. internal final class JMCallKitEmitter: NSObject, CXProviderDelegate {
  20. private var listeners = Set<JMCallKitEventListenerWrapper>()
  21. internal override init() {}
  22. // MARK: - Add/remove listeners
  23. func addListener(_ listener: JMCallKitListener) {
  24. let wrapper = JMCallKitEventListenerWrapper(listener: listener)
  25. objc_sync_enter(listeners)
  26. listeners.insert(wrapper)
  27. objc_sync_exit(listeners)
  28. }
  29. func removeListener(_ listener: JMCallKitListener) {
  30. let wrapper = JMCallKitEventListenerWrapper(listener: listener)
  31. objc_sync_enter(listeners)
  32. listeners.remove(wrapper)
  33. objc_sync_exit(listeners)
  34. }
  35. // MARK: - CXProviderDelegate
  36. func providerDidReset(_ provider: CXProvider) {
  37. objc_sync_enter(listeners)
  38. listeners.forEach { $0.listener?.providerDidReset?() }
  39. objc_sync_exit(listeners)
  40. }
  41. func provider(_ provider: CXProvider, perform action: CXAnswerCallAction) {
  42. objc_sync_enter(listeners)
  43. listeners.forEach {
  44. $0.listener?.performAnswerCall?(UUID: action.callUUID)
  45. }
  46. objc_sync_exit(listeners)
  47. action.fulfill()
  48. }
  49. func provider(_ provider: CXProvider, perform action: CXEndCallAction) {
  50. objc_sync_enter(listeners)
  51. listeners.forEach {
  52. $0.listener?.performEndCall?(UUID: action.callUUID)
  53. }
  54. objc_sync_exit(listeners)
  55. action.fulfill()
  56. }
  57. func provider(_ provider: CXProvider, perform action: CXSetMutedCallAction) {
  58. objc_sync_enter(listeners)
  59. listeners.forEach {
  60. $0.listener?.performSetMutedCall?(UUID: action.callUUID,
  61. isMuted: action.isMuted)
  62. }
  63. objc_sync_exit(listeners)
  64. action.fulfill()
  65. }
  66. func provider(_ provider: CXProvider, perform action: CXStartCallAction) {
  67. objc_sync_enter(listeners)
  68. listeners.forEach {
  69. $0.listener?.performStartCall?(UUID: action.callUUID,
  70. isVideo: action.isVideo)
  71. }
  72. objc_sync_exit(listeners)
  73. action.fulfill()
  74. }
  75. func provider(_ provider: CXProvider,
  76. didActivate audioSession: AVAudioSession) {
  77. objc_sync_enter(listeners)
  78. listeners.forEach {
  79. $0.listener?.providerDidActivateAudioSession?(session: audioSession)
  80. }
  81. objc_sync_exit(listeners)
  82. }
  83. func provider(_ provider: CXProvider,
  84. didDeactivate audioSession: AVAudioSession) {
  85. objc_sync_enter(listeners)
  86. listeners.forEach {
  87. $0.listener?.providerDidDeactivateAudioSession?(
  88. session: audioSession)
  89. }
  90. objc_sync_exit(listeners)
  91. }
  92. }
  93. fileprivate struct JMCallKitEventListenerWrapper: Hashable {
  94. public var hashValue: Int
  95. internal weak var listener: JMCallKitListener?
  96. public init(listener: JMCallKitListener) {
  97. self.listener = listener
  98. self.hashValue = listener.hash
  99. }
  100. public static func ==(lhs: JMCallKitEventListenerWrapper,
  101. rhs: JMCallKitEventListenerWrapper) -> Bool {
  102. // XXX We're aware that "[t]wo instances with equal hash values are not
  103. // necessarily equal to each other."
  104. return lhs.hashValue == rhs.hashValue
  105. }
  106. }