Improve handling of call service edge cases.

// FREEBIE
pull/1/head
Matthew Chen 8 years ago
parent f920300f28
commit 3c4955840d

@ -74,8 +74,8 @@ enum CallError: Error {
case assertionError(description: String) case assertionError(description: String)
case disconnected case disconnected
case externalError(underlyingError: Error) case externalError(underlyingError: Error)
case timeout(description: String, call: SignalCall) case timeout(description: String)
case obsoleteCall(description: String, call: SignalCall) case obsoleteCall(description: String)
} }
// Should be roughly synced with Android client for consistency // Should be roughly synced with Android client for consistency
@ -292,7 +292,7 @@ protocol CallServiceObserver: class {
Logger.debug("\(self.TAG) got ice servers:\(iceServers)") Logger.debug("\(self.TAG) got ice servers:\(iceServers)")
guard self.call == call else { guard self.call == call else {
return Promise(error: CallError.obsoleteCall(description:"obsolete call in \(#function)", call:call)) return Promise(error: CallError.obsoleteCall(description:"obsolete call in \(#function)"))
} }
let useTurnOnly = Environment.getCurrent().preferences.doCallsHideIPAddress() let useTurnOnly = Environment.getCurrent().preferences.doCallsHideIPAddress()
@ -306,7 +306,7 @@ protocol CallServiceObserver: class {
return self.peerConnectionClient!.createOffer() return self.peerConnectionClient!.createOffer()
}.then { (sessionDescription: HardenedRTCSessionDescription) -> Promise<Void> in }.then { (sessionDescription: HardenedRTCSessionDescription) -> Promise<Void> in
guard self.call == call else { guard self.call == call else {
return Promise(error: CallError.obsoleteCall(description:"obsolete call in \(#function)", call:call)) return Promise(error: CallError.obsoleteCall(description:"obsolete call in \(#function)"))
} }
return self.peerConnectionClient!.setLocalSessionDescription(sessionDescription).then { return self.peerConnectionClient!.setLocalSessionDescription(sessionDescription).then {
@ -316,7 +316,7 @@ protocol CallServiceObserver: class {
} }
}.then { }.then {
guard self.call == call else { guard self.call == call else {
return Promise(error: CallError.obsoleteCall(description:"obsolete call in \(#function)", call:call)) return Promise(error: CallError.obsoleteCall(description:"obsolete call in \(#function)"))
} }
let (callConnectedPromise, fulfill, _) = Promise<Void>.pending() let (callConnectedPromise, fulfill, _) = Promise<Void>.pending()
@ -325,7 +325,7 @@ protocol CallServiceObserver: class {
// Don't let the outgoing call ring forever. We don't support inbound ringing forever anyway. // Don't let the outgoing call ring forever. We don't support inbound ringing forever anyway.
let timeout: Promise<Void> = after(interval: TimeInterval(connectingTimeoutSeconds)).then { () -> Void in let timeout: Promise<Void> = after(interval: TimeInterval(connectingTimeoutSeconds)).then { () -> Void in
// rejecting a promise by throwing is safely a no-op if the promise has already been fulfilled // rejecting a promise by throwing is safely a no-op if the promise has already been fulfilled
throw CallError.timeout(description: "timed out waiting to receive call answer", call: call) throw CallError.timeout(description: "timed out waiting to receive call answer")
} }
return race(timeout, callConnectedPromise) return race(timeout, callConnectedPromise)
@ -481,7 +481,7 @@ protocol CallServiceObserver: class {
call = newCall call = newCall
let backgroundTask = UIApplication.shared.beginBackgroundTask { let backgroundTask = UIApplication.shared.beginBackgroundTask {
let timeout = CallError.timeout(description: "background task time ran out before call connected.", call: newCall) let timeout = CallError.timeout(description: "background task time ran out before call connected.")
DispatchQueue.main.async { DispatchQueue.main.async {
guard self.call == newCall else { guard self.call == newCall else {
Logger.warn("\(self.TAG) ignoring obsolete call in \(#function)") Logger.warn("\(self.TAG) ignoring obsolete call in \(#function)")
@ -497,7 +497,7 @@ protocol CallServiceObserver: class {
// FIXME for first time call recipients I think we'll see mic/camera permission requests here, // FIXME for first time call recipients I think we'll see mic/camera permission requests here,
// even though, from the users perspective, no incoming call is yet visible. // even though, from the users perspective, no incoming call is yet visible.
guard self.call == newCall else { guard self.call == newCall else {
throw CallError.obsoleteCall(description: "getIceServers() response for obsolete call", call:newCall) throw CallError.obsoleteCall(description: "getIceServers() response for obsolete call")
} }
assert(self.peerConnectionClient == nil, "Unexpected PeerConnectionClient instance") assert(self.peerConnectionClient == nil, "Unexpected PeerConnectionClient instance")
@ -517,7 +517,7 @@ protocol CallServiceObserver: class {
return self.peerConnectionClient!.negotiateSessionDescription(remoteDescription: offerSessionDescription, constraints: constraints) return self.peerConnectionClient!.negotiateSessionDescription(remoteDescription: offerSessionDescription, constraints: constraints)
}.then { (negotiatedSessionDescription: HardenedRTCSessionDescription) in }.then { (negotiatedSessionDescription: HardenedRTCSessionDescription) in
guard self.call == newCall else { guard self.call == newCall else {
throw CallError.obsoleteCall(description: "negotiateSessionDescription() response for obsolete call", call:newCall) throw CallError.obsoleteCall(description: "negotiateSessionDescription() response for obsolete call")
} }
Logger.debug("\(self.TAG) set the remote description") Logger.debug("\(self.TAG) set the remote description")
@ -527,7 +527,7 @@ protocol CallServiceObserver: class {
return self.messageSender.sendCallMessage(callAnswerMessage) return self.messageSender.sendCallMessage(callAnswerMessage)
}.then { }.then {
guard self.call == newCall else { guard self.call == newCall else {
throw CallError.obsoleteCall(description: "sendCallMessage() response for obsolete call", call:newCall) throw CallError.obsoleteCall(description: "sendCallMessage() response for obsolete call")
} }
Logger.debug("\(self.TAG) successfully sent callAnswerMessage") Logger.debug("\(self.TAG) successfully sent callAnswerMessage")
@ -535,7 +535,7 @@ protocol CallServiceObserver: class {
let timeout: Promise<Void> = after(interval: TimeInterval(connectingTimeoutSeconds)).then { () -> Void in let timeout: Promise<Void> = after(interval: TimeInterval(connectingTimeoutSeconds)).then { () -> Void in
// rejecting a promise by throwing is safely a no-op if the promise has already been fulfilled // rejecting a promise by throwing is safely a no-op if the promise has already been fulfilled
throw CallError.timeout(description: "timed out waiting for call to connect", call: newCall) throw CallError.timeout(description: "timed out waiting for call to connect")
} }
// This will be fulfilled (potentially) by the RTCDataChannel delegate method // This will be fulfilled (potentially) by the RTCDataChannel delegate method
@ -544,7 +544,7 @@ protocol CallServiceObserver: class {
return race(promise, timeout) return race(promise, timeout)
}.then { }.then {
guard self.call == newCall else { guard self.call == newCall else {
throw CallError.obsoleteCall(description: "time out for obsolete incoming call", call:newCall) throw CallError.obsoleteCall(description: "time out for obsolete incoming call")
} }
Logger.info("\(self.TAG) incoming call connected.") Logger.info("\(self.TAG) incoming call connected.")

Loading…
Cancel
Save