@ -160,6 +160,17 @@ protocol CallServiceObserver: class {
// U s e d t o c o o r d i n a t e p r o m i s e s a c r o s s d e l e g a t e m e t h o d s
private var fulfillCallConnectedPromise : ( ( ) -> Void ) ?
/* *
* In the process of establishing a connection between the clients ( ICE process ) we must exchange ICE updates .
* Because this happens via Signal Service it ' s possible the callee user has not accepted any change in the caller ' s
* identity . In which case * each * ICE update would cause an " identity change " warning on the callee ' s device . Since
* this could be several messages , the caller stores all ICE updates until receiving positive confirmation that the
* callee has received a message from us . This positive confirmation comes in the form of the callees ` CallAnswer `
* message .
*/
var sendIceUpdatesImmediately = true
var pendingIceUpdateMessages = [ OWSCallIceUpdateMessage ] ( )
// U s e d b y w a i t F o r P e e r C o n n e c t i o n C l i e n t t o m a k e s u r e a n y r e c e i v e d
// I C E m e s s a g e s w a i t u n t i l t h e p e e r c o n n e c t i o n c l i e n t i s s e t u p .
private var fulfillPeerConnectionClientPromise : ( ( ) -> Void ) ?
@ -260,6 +271,9 @@ protocol CallServiceObserver: class {
self . call = call
sendIceUpdatesImmediately = false
pendingIceUpdateMessages = [ ]
let callRecord = TSCall ( timestamp : NSDate . ows_millisecondTimeStamp ( ) , withCallNumber : call . remotePhoneNumber , callType : RPRecentCallTypeOutgoingIncomplete , in : call . thread )
callRecord . save ( )
call . callRecord = callRecord
@ -349,6 +363,19 @@ protocol CallServiceObserver: class {
return
}
// N o w t h a t w e k n o w t h e r e c i p i e n t t r u s t s o u r i d e n t i t y , w e n o l o n g e r n e e d t o e n q u e u e I C E u p d a t e s .
self . sendIceUpdatesImmediately = true
if pendingIceUpdateMessages . count > 0 {
Logger . error ( " \( self . TAG ) Sending \( pendingIceUpdateMessages . count ) pendingIceUpdateMessages " )
let callMessage = OWSOutgoingCallMessage ( thread : thread , iceUpdateMessages : pendingIceUpdateMessages )
let sendPromise = messageSender . sendCallMessage ( callMessage ) . catch { error in
Logger . error ( " \( self . TAG ) failed to send ice updates in \( #function ) with error: \( error ) " )
}
sendPromise . retainUntilComplete ( )
}
guard let peerConnectionClient = self . peerConnectionClient else {
handleFailedCall ( failedCall : call , error : CallError . assertionError ( description : " peerConnectionClient was unexpectedly nil in \( #function ) " ) )
return
@ -648,8 +675,19 @@ protocol CallServiceObserver: class {
let iceUpdateMessage = OWSCallIceUpdateMessage ( callId : call . signalingId , sdp : iceCandidate . sdp , sdpMLineIndex : iceCandidate . sdpMLineIndex , sdpMid : iceCandidate . sdpMid )
let callMessage = OWSOutgoingCallMessage ( thread : call . thread , iceUpdateMessage : iceUpdateMessage )
self . messageSender . sendCallMessage ( callMessage ) . retainUntilComplete ( )
if self . sendIceUpdatesImmediately {
Logger . info ( " \( TAG ) in \( #function ) . Sending immediately. " )
let callMessage = OWSOutgoingCallMessage ( thread : call . thread , iceUpdateMessage : iceUpdateMessage )
let sendPromise = self . messageSender . sendCallMessage ( callMessage )
sendPromise . retainUntilComplete ( )
} else {
// F o r o u t g o i n g m e s s a g e s , w e w a i t t o s e n d i c e u p d a t e s u n t i l w e ' r e s u r e c l i e n t r e c e i v e d o u r c a l l m e s s a g e .
// e . g . i f t h e c l i e n t h a s b l o c k e d o u r m e s s a g e d u e t o a n i d e n t i t y c h a n g e , w e ' d o t h e r w i s e
// b o m b a r d t h e m w i t h a b u n c h * m o r e * u n d e c i p h e r a b l e m e s s a g e s .
Logger . info ( " \( TAG ) in \( #function ) . Enqueing for later. " )
self . pendingIceUpdateMessages . append ( iceUpdateMessage )
return
}
}
/* *
@ -1273,6 +1311,9 @@ protocol CallServiceObserver: class {
self . call ? . removeAllObservers ( )
self . call = nil
self . sendIceUpdatesImmediately = true
Logger . info ( " \( TAG ) clearing pendingIceUpdateMessages " )
self . pendingIceUpdateMessages = [ ]
self . fulfillCallConnectedPromise = nil
// I n c a s e w e ' r e s t i l l w a i t i n g o n t h e p e e r c o n n e c t i o n s e t u p s o m e w h e r e , w e n e e d t o r e j e c t i t t o a v o i d a m e m o r y l e a k .