From 6cdf13ea5f4f781aa117dd67de6067f34822b399 Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Wed, 8 Feb 2017 14:27:29 -0500 Subject: [PATCH] Only time out the intended call previously a followup call could get clobbered by the previous calls timeout // FREEBIE --- Signal/src/call/CallService.swift | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/Signal/src/call/CallService.swift b/Signal/src/call/CallService.swift index 187c29bf7..3a1882b2a 100644 --- a/Signal/src/call/CallService.swift +++ b/Signal/src/call/CallService.swift @@ -74,7 +74,7 @@ enum CallError: Error { case assertionError(description: String) case disconnected case externalError(underlyingError: Error) - case timeout(description: String) + case timeout(description: String, call: SignalCall) } // Should be roughly synced with Android client for consistency @@ -318,7 +318,7 @@ protocol CallServiceObserver: class { // Don't let the outgoing call ring forever. We don't support inbound ringing forever anyway. let timeout: Promise = after(interval: TimeInterval(connectingTimeoutSeconds)).then { () -> Void in // 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") + throw CallError.timeout(description: "timed out waiting to receive call answer", call: call) } return race(timeout, callConnectedPromise) @@ -450,7 +450,7 @@ protocol CallServiceObserver: class { call = newCall let backgroundTask = UIApplication.shared.beginBackgroundTask { - let timeout = CallError.timeout(description: "background task time ran out before call connected.") + let timeout = CallError.timeout(description: "background task time ran out before call connected.", call: newCall) DispatchQueue.main.async { guard self.call == newCall else { return @@ -496,7 +496,7 @@ protocol CallServiceObserver: class { let timeout: Promise = after(interval: TimeInterval(connectingTimeoutSeconds)).then { () -> Void in // 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") + throw CallError.timeout(description: "timed out waiting for call to connect", call: newCall) } // This will be fulfilled (potentially) by the RTCDataChannel delegate method @@ -1090,6 +1090,14 @@ protocol CallServiceObserver: class { Logger.error("\(TAG) call failed with error: \(error)") if let call = self.call { + + if case .timeout(description: _, call: let timedOutCall) = error { + guard timedOutCall == call else { + Logger.debug("Ignoring timeout for previous call") + return + } + } + // It's essential to set call.state before terminateCall, because terminateCall nils self.call call.error = error call.state = .localFailure