Wip smashign providerdelgate into UIAdaptee

pull/1/head
Michael Kirk 8 years ago committed by Matthew Chen
parent 6eecef99ba
commit ce3780e44a

@ -3,6 +3,9 @@
import Foundation import Foundation
/**
* Present call related notifications to the user.
*/
@objc(OWSCallNotificationsAdapter) @objc(OWSCallNotificationsAdapter)
class CallNotificationsAdapter: NSObject { class CallNotificationsAdapter: NSObject {
@ -10,9 +13,9 @@ class CallNotificationsAdapter: NSObject {
let adaptee: OWSCallNotificationsAdaptee let adaptee: OWSCallNotificationsAdaptee
override init() { override init() {
// TODO We can't mix UINotification (NotificationManager) with the UNNotifications // TODO We can't mix UILocalNotification (NotificationManager) with the UNNotifications
// Because registering message categories in one, clobbers the notifications in the other. // Because registering message categories in one, clobbers the registered categories from the other
// We have to first port *all* the existing UINotifications to UNNotifications // We have to first port *all* the existing UINotification categories to UNNotifications
// which is a good thing to do, but in trying to limit the scope of changes that's been // which is a good thing to do, but in trying to limit the scope of changes that's been
// left out for now. // left out for now.
// if #available(iOS 10.0, *) { // if #available(iOS 10.0, *) {

@ -3,6 +3,10 @@
import Foundation import Foundation
/**
* CallKit backed implementation of UI Activity related to Signal Calls
* TODO: Code Cleanup: It might be more straight forward to roll this into the CallKitProviderDelegate.
*/
@available(iOS 10.0, *) @available(iOS 10.0, *)
class CallKitCallUIAdaptee: CallUIAdaptee { class CallKitCallUIAdaptee: CallUIAdaptee {
@ -13,15 +17,15 @@ class CallKitCallUIAdaptee: CallUIAdaptee {
init(callService: CallService, notificationsAdapter: CallNotificationsAdapter) { init(callService: CallService, notificationsAdapter: CallNotificationsAdapter) {
self.callManager = CallKitCallManager() self.callManager = CallKitCallManager()
self.providerDelegate = CallKitProviderDelegate(callManager: callManager, callService: callService) self.providerDelegate = CallKitProviderDelegate(callService: callService, notificationsAdapter: notificationsAdapter)
self.notificationsAdapter = notificationsAdapter self.notificationsAdapter = notificationsAdapter
} }
public func startOutgoingCall(_ call: SignalCall) { public func startOutgoingCall(_ call: SignalCall) {
// Add the new outgoing call to the app's list of calls. // Add the new outgoing call to the app's list of calls.
// So we can find it in the provider delegate callbacks. // So we can find it in the provider delegate callbacks.
self.callManager.addCall(call) // self.callManager.addCall(call)
providerDelegate.callManager.startCall(call) // providerDelegate.callManager.startCall(call)
} }
public func reportIncomingCall(_ call: SignalCall, callerName: String, audioManager: SignalCallAudioManager) { public func reportIncomingCall(_ call: SignalCall, callerName: String, audioManager: SignalCallAudioManager) {
@ -29,15 +33,15 @@ class CallKitCallUIAdaptee: CallUIAdaptee {
// Crux is, the peerconnectionclient is what controls the audio channel. // Crux is, the peerconnectionclient is what controls the audio channel.
// But a peerconnectionclient is per call. // But a peerconnectionclient is per call.
// While this providerDelegate is an app singleton. // While this providerDelegate is an app singleton.
providerDelegate.audioManager = audioManager // providerDelegate.audioManager = audioManager
//
providerDelegate.reportIncomingCall(call) { error in // providerDelegate.reportIncomingCall(call) { error in
if error == nil { // if error == nil {
Logger.debug("\(self.TAG) successfully reported incoming call.") // Logger.debug("\(self.TAG) successfully reported incoming call.")
} else { // } else {
Logger.error("\(self.TAG) providerDelegate.reportIncomingCall failed with error: \(error)") // Logger.error("\(self.TAG) providerDelegate.reportIncomingCall failed with error: \(error)")
} // }
} // }
} }
public func reportMissedCall(_ call: SignalCall, callerName: String) { public func reportMissedCall(_ call: SignalCall, callerName: String) {

@ -6,12 +6,19 @@ import UIKit
import CallKit import CallKit
import AVFoundation import AVFoundation
/**
* Connects requests for CallKit actions (CXActions) with their corresponding consequences in CallService
*
* TODO: Code cleanup: The responsibilities largely overlap with the CallKitCallUIAdapter. Maybe they should be merged.
*/
@available(iOS 10.0, *) @available(iOS 10.0, *)
final class CallKitProviderDelegate: NSObject, CXProviderDelegate { final class CallKitProviderDelegate: NSObject, CallUIAdaptee, CXProviderDelegate {
let TAG = "[CallKitProviderDelegate]" let TAG = "[CallKitProviderDelegate]"
let callManager: CallKitCallManager
let callService: CallService private let callManager: CallKitCallManager
private let callService: CallService
internal let notificationsAdapter: CallNotificationsAdapter
private let provider: CXProvider private let provider: CXProvider
// FIXME - I might be thinking about this the wrong way. // FIXME - I might be thinking about this the wrong way.
@ -22,16 +29,6 @@ final class CallKitProviderDelegate: NSObject, CXProviderDelegate {
// It seems like a mess to reconcile this difference in cardinality. But... here we are. // It seems like a mess to reconcile this difference in cardinality. But... here we are.
var audioManager: SignalCallAudioManager? var audioManager: SignalCallAudioManager?
init(callManager: CallKitCallManager, callService: CallService) {
self.callService = callService
self.callManager = callManager
provider = CXProvider(configuration: type(of: self).providerConfiguration)
super.init()
provider.setDelegate(self, queue: nil)
}
/// The app's provider configuration, representing its CallKit capabilities /// The app's provider configuration, representing its CallKit capabilities
static var providerConfiguration: CXProviderConfiguration { static var providerConfiguration: CXProviderConfiguration {
let localizedName = NSLocalizedString("APPLICATION_NAME", comment: "Name of application") let localizedName = NSLocalizedString("APPLICATION_NAME", comment: "Name of application")
@ -52,8 +49,28 @@ final class CallKitProviderDelegate: NSObject, CXProviderDelegate {
return providerConfiguration return providerConfiguration
} }
/// Use CXProvider to report the incoming call to the system init(callService: CallService, notificationsAdapter: CallNotificationsAdapter) {
func reportIncomingCall(_ call: SignalCall, completion: ((NSError?) -> Void)? = nil) { self.callManager = CallKitCallManager()
self.callService = callService
self.notificationsAdapter = notificationsAdapter
self.provider = CXProvider(configuration: type(of: self).providerConfiguration)
super.init()
self.provider.setDelegate(self, queue: nil)
}
// MARK: CallUIAdaptee
internal func startOutgoingCall(_ call: SignalCall) {
// Add the new outgoing call to the app's list of calls.
// So we can find it in the provider delegate callbacks.
callManager.addCall(call)
callManager.startCall(call)
}
// TODO CodeCleanup: remove unused audiomanager
internal func reportIncomingCall(_ call: SignalCall, callerName: String, audioManager: SignalCallAudioManager) {
// Construct a CXCallUpdate describing the incoming call, including the caller. // Construct a CXCallUpdate describing the incoming call, including the caller.
let update = CXCallUpdate() let update = CXCallUpdate()
update.remoteHandle = CXHandle(type: .phoneNumber, value: call.remotePhoneNumber) update.remoteHandle = CXHandle(type: .phoneNumber, value: call.remotePhoneNumber)
@ -65,14 +82,27 @@ final class CallKitProviderDelegate: NSObject, CXProviderDelegate {
Only add incoming call to the app's list of calls if the call was allowed (i.e. there was no error) Only add incoming call to the app's list of calls if the call was allowed (i.e. there was no error)
since calls may be "denied" for various legitimate reasons. See CXErrorCodeIncomingCallError. since calls may be "denied" for various legitimate reasons. See CXErrorCodeIncomingCallError.
*/ */
if error == nil { guard error == nil else {
self.callManager.addCall(call) Logger.error("\(self.TAG) failed to report new incoming call")
return
} }
completion?(error as? NSError) self.callManager.addCall(call)
} }
} }
internal func answerCall(_ call: SignalCall) {
showCall(call)
}
internal func declineCall(_ call: SignalCall) {
callManager.end(call: call)
}
internal func endCall(_ call: SignalCall) {
callManager.end(call: call)
}
// MARK: CXProviderDelegate // MARK: CXProviderDelegate
func providerDidReset(_ provider: CXProvider) { func providerDidReset(_ provider: CXProvider) {

@ -6,6 +6,8 @@ import PromiseKit
import CallKit import CallKit
protocol CallUIAdaptee { protocol CallUIAdaptee {
var notificationsAdapter: CallNotificationsAdapter { get }
func startOutgoingCall(_ call: SignalCall) func startOutgoingCall(_ call: SignalCall)
func reportIncomingCall(_ call: SignalCall, callerName: String, audioManager: SignalCallAudioManager) func reportIncomingCall(_ call: SignalCall, callerName: String, audioManager: SignalCallAudioManager)
func reportMissedCall(_ call: SignalCall, callerName: String) func reportMissedCall(_ call: SignalCall, callerName: String)
@ -14,11 +16,16 @@ protocol CallUIAdaptee {
func endCall(_ call: SignalCall) func endCall(_ call: SignalCall)
} }
// Shared default implementations
extension CallUIAdaptee { extension CallUIAdaptee {
public func showCall(_ call: SignalCall) { internal func showCall(_ call: SignalCall) {
let callNotificationName = CallService.callServiceActiveCallNotificationName() let callNotificationName = CallService.callServiceActiveCallNotificationName()
NotificationCenter.default.post(name: NSNotification.Name(rawValue: callNotificationName), object: call) NotificationCenter.default.post(name: NSNotification.Name(rawValue: callNotificationName), object: call)
} }
internal func reportMissedCall(_ call: SignalCall, callerName: String) {
notificationsAdapter.presentMissedCall(call, callerName: callerName)
}
} }
/** /**
@ -34,14 +41,14 @@ class CallUIAdapter {
required init(callService: CallService, contactsManager: OWSContactsManager, notificationsAdapter: CallNotificationsAdapter) { required init(callService: CallService, contactsManager: OWSContactsManager, notificationsAdapter: CallNotificationsAdapter) {
self.contactsManager = contactsManager self.contactsManager = contactsManager
if Platform.isSimulator { if Platform.isSimulator {
// Callkit doesn't seem entirely supported in simulator. // CallKit doesn't seem entirely supported in simulator.
// e.g. you can't receive calls in the call screen. // e.g. you can't receive calls in the call screen.
// So we use the non-call kit call UI. // So we use the non-call kit call UI.
Logger.info("\(TAG) choosing non-callkit adaptee for simulator.") Logger.info("\(TAG) choosing non-callkit adaptee for simulator.")
adaptee = NonCallKitCallUIAdaptee(callService: callService, notificationsAdapter: notificationsAdapter) adaptee = NonCallKitCallUIAdaptee(callService: callService, notificationsAdapter: notificationsAdapter)
} else if #available(iOS 10.0, *) { } else if #available(iOS 10.0, *) {
Logger.info("\(TAG) choosing callkit adaptee for iOS10+") Logger.info("\(TAG) choosing callkit adaptee for iOS10+")
adaptee = CallKitCallUIAdaptee(callService: callService, notificationsAdapter: notificationsAdapter) adaptee = CallKitProviderDelegate(callService: callService, notificationsAdapter: notificationsAdapter)
} else { } else {
Logger.info("\(TAG) choosing non-callkit adaptee for older iOS") Logger.info("\(TAG) choosing non-callkit adaptee for older iOS")
adaptee = NonCallKitCallUIAdaptee(callService: callService, notificationsAdapter: notificationsAdapter) adaptee = NonCallKitCallUIAdaptee(callService: callService, notificationsAdapter: notificationsAdapter)

Loading…
Cancel
Save