mirror of https://github.com/oxen-io/session-ios
parent
724a1c9b20
commit
bbfd9ba74d
@ -0,0 +1,94 @@
|
||||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
/**
|
||||
* Creates an outbound call via either Redphone or WebRTC depending on participant preferences.
|
||||
*/
|
||||
@objc class OutboundCallInitiator: NSObject {
|
||||
let TAG = "[OutboundCallInitiator]"
|
||||
|
||||
let callUIAdapter: CallUIAdapter
|
||||
let redphoneManager: PhoneManager
|
||||
let contactsManager: OWSContactsManager
|
||||
let contactsUpdater: ContactsUpdater
|
||||
|
||||
init(redphoneManager: PhoneManager, callUIAdapter: CallUIAdapter, contactsManager: OWSContactsManager, contactsUpdater: ContactsUpdater) {
|
||||
self.redphoneManager = redphoneManager
|
||||
self.callUIAdapter = callUIAdapter
|
||||
|
||||
self.contactsManager = contactsManager
|
||||
self.contactsUpdater = contactsUpdater
|
||||
}
|
||||
|
||||
/**
|
||||
* |handle| is a user formatted phone number, e.g. from a system contacts entry
|
||||
*/
|
||||
public func initiateCall(handle: String) -> Bool {
|
||||
Logger.info("\(TAG) in \(#function) with handle: \(handle)")
|
||||
guard let recipientId = PhoneNumber(fromUserSpecifiedText: handle).toE164() else {
|
||||
Logger.warn("\(TAG) unable to parse signalId from phone number: \(handle)")
|
||||
return false
|
||||
}
|
||||
|
||||
return initiateCall(recipientId: recipientId)
|
||||
}
|
||||
|
||||
/**
|
||||
* |recipientId| is a e164 formatted phone number.
|
||||
*/
|
||||
public func initiateCall(recipientId: String) -> Bool {
|
||||
|
||||
let localWantsWebRTC = Environment.preferences().isWebRTCEnabled()
|
||||
if !localWantsWebRTC {
|
||||
return self.initiateRedphoneCall(recipientId: recipientId)
|
||||
}
|
||||
|
||||
// Since users can toggle this setting, which is only communicated during contact sync, it's easy to imagine the
|
||||
// preference getting stale. Especially as users are toggling the feature to test calls. So here, we opt for a
|
||||
// blocking network request *every* time we place a call to make sure we've got up to date preferences.
|
||||
//
|
||||
// e.g. The following would suffice if we weren't worried about stale preferences.
|
||||
// SignalRecipient *recipient = [SignalRecipient recipientWithTextSecureIdentifier:self.thread.contactIdentifier];
|
||||
self.contactsUpdater.lookupIdentifier(recipientId,
|
||||
success: { recipient in
|
||||
let remoteWantsWebRTC = recipient.supportsWebRTC
|
||||
Logger.debug("\(self.TAG) localWantsWebRTC: \(localWantsWebRTC), remoteWantsWebRTC: \(remoteWantsWebRTC)")
|
||||
|
||||
if localWantsWebRTC, remoteWantsWebRTC {
|
||||
_ = self.initiateWebRTCAudioCall(recipientId: recipientId)
|
||||
} else {
|
||||
_ = self.initiateRedphoneCall(recipientId: recipientId)
|
||||
}
|
||||
},
|
||||
failure: { error in
|
||||
Logger.warn("\(self.TAG) looking up recipientId: \(recipientId) failed with error \(error)")
|
||||
// TODO fail with alert. e.g. when someone tries to call a non signal user from their contacts we should inform them.
|
||||
})
|
||||
|
||||
// Since we've already dispatched async to make sure we have fresh webrtc preference data
|
||||
// we don't have a meaningful value to return here - but we're not using it anway. =/
|
||||
return true
|
||||
}
|
||||
|
||||
private func initiateRedphoneCall(recipientId: String) -> Bool {
|
||||
Logger.info("\(TAG) Placing redphone call to: \(recipientId)")
|
||||
|
||||
let number = PhoneNumber.tryParsePhoneNumber(fromUserSpecifiedText: recipientId)
|
||||
let contact = self.contactsManager.latestContact(for: number)
|
||||
assert(number != nil)
|
||||
assert(contact != nil)
|
||||
|
||||
redphoneManager.initiateOutgoingCall(to: contact, atRemoteNumber: number)
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
private func initiateWebRTCAudioCall(recipientId: String) -> Bool {
|
||||
callUIAdapter.callBack(recipientId: recipientId)
|
||||
return true
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue