diff --git a/Session/Calls/Call Management/SessionCallManager.swift b/Session/Calls/Call Management/SessionCallManager.swift index 0118933d9..235992f4f 100644 --- a/Session/Calls/Call Management/SessionCallManager.swift +++ b/Session/Calls/Call Management/SessionCallManager.swift @@ -105,10 +105,11 @@ public final class SessionCallManager: NSObject { guard let call = currentCall else { return } if let reason = reason { self.provider.reportCall(with: call.callID, endedAt: nil, reason: reason) - if reason == .unanswered { - call.updateCallMessage(mode: .unanswered) - } else { - call.updateCallMessage(mode: .remote) + switch (reason) { + case .unanswered: call.updateCallMessage(mode: .unanswered) + case .declinedElsewhere: call.updateCallMessage(mode: .local) + case .answeredElsewhere: break + default: call.updateCallMessage(mode: .remote) } } else { call.updateCallMessage(mode: .local) diff --git a/Session/Meta/AppDelegate.swift b/Session/Meta/AppDelegate.swift index 588823759..7aef82e4f 100644 --- a/Session/Meta/AppDelegate.swift +++ b/Session/Meta/AppDelegate.swift @@ -17,7 +17,12 @@ extension AppDelegate { conversationVC.inputAccessoryView?.alpha = 0 } presentingVC.present(callVC, animated: true, completion: nil) - + } + + @objc func dismissAllCallUI() { + if let currentBanner = IncomingCallBanner.current { currentBanner.dismiss() } + if let callVC = CurrentAppContext().frontmostViewController() as? CallVC { callVC.handleEndCallMessage() } + if let miniCallView = MiniCallView.current { miniCallView.dismiss() } } @objc func setUpCallHandling() { @@ -72,21 +77,29 @@ extension AppDelegate { MessageReceiver.handleAnswerCallMessage = { message in DispatchQueue.main.async { guard let call = AppEnvironment.shared.callManager.currentCall, message.uuid! == call.uuid else { return } - AppEnvironment.shared.callManager.invalidateTimeoutTimer() - call.hasStartedConnecting = true - let sdp = RTCSessionDescription(type: .answer, sdp: message.sdps![0]) - call.didReceiveRemoteSDP(sdp: sdp) - guard let callVC = CurrentAppContext().frontmostViewController() as? CallVC else { return } - callVC.handleAnswerMessage(message) + if message.sender! == getUserHexEncodedPublicKey() { + self.dismissAllCallUI() + AppEnvironment.shared.callManager.reportCurrentCallEnded(reason: .answeredElsewhere) + } else { + AppEnvironment.shared.callManager.invalidateTimeoutTimer() + call.hasStartedConnecting = true + let sdp = RTCSessionDescription(type: .answer, sdp: message.sdps![0]) + call.didReceiveRemoteSDP(sdp: sdp) + guard let callVC = CurrentAppContext().frontmostViewController() as? CallVC else { return } + callVC.handleAnswerMessage(message) + } } } // End call messages MessageReceiver.handleEndCallMessage = { message in DispatchQueue.main.async { - if let currentBanner = IncomingCallBanner.current { currentBanner.dismiss() } - if let callVC = CurrentAppContext().frontmostViewController() as? CallVC { callVC.handleEndCallMessage() } - if let miniCallView = MiniCallView.current { miniCallView.dismiss() } - AppEnvironment.shared.callManager.reportCurrentCallEnded(reason: .remoteEnded) + guard let call = AppEnvironment.shared.callManager.currentCall, message.uuid! == call.uuid else { return } + self.dismissAllCallUI() + if message.sender! == getUserHexEncodedPublicKey() { + AppEnvironment.shared.callManager.reportCurrentCallEnded(reason: .declinedElsewhere) + } else { + AppEnvironment.shared.callManager.reportCurrentCallEnded(reason: .remoteEnded) + } } } } diff --git a/SessionMessagingKit/Messages/Control Messages/CallMessage.swift b/SessionMessagingKit/Messages/Control Messages/CallMessage.swift index cd3609991..0a364c7e7 100644 --- a/SessionMessagingKit/Messages/Control Messages/CallMessage.swift +++ b/SessionMessagingKit/Messages/Control Messages/CallMessage.swift @@ -9,6 +9,7 @@ public final class CallMessage : ControlMessage { public var sdps: [String]? public override var ttl: UInt64 { 2 * 60 * 1000 } + public override var isSelfSendValid: Bool { true } // NOTE: Multiple ICE candidates may be batched together for performance diff --git a/SessionMessagingKit/Sending & Receiving/MessageSender.swift b/SessionMessagingKit/Sending & Receiving/MessageSender.swift index 0206929b1..bbe0a1c56 100644 --- a/SessionMessagingKit/Sending & Receiving/MessageSender.swift +++ b/SessionMessagingKit/Sending & Receiving/MessageSender.swift @@ -135,8 +135,8 @@ public final class MessageSender : NSObject { // • a sync message // • a closed group control message of type `new` // • an unsend request - let isNewClosedGroupControlMessage = given(message as? ClosedGroupControlMessage) { if case .new = $0.kind { return true } else { return false } } ?? false - guard !isSelfSend || message is ConfigurationMessage || isSyncMessage || isNewClosedGroupControlMessage || message is UnsendRequest else { + // • a call message of type `answer` or `endCall` + guard !isSelfSend || isSyncMessage || shouldSyncMessage(message) else { storage.write(with: { transaction in MessageSender.handleSuccessfulMessageSend(message, to: destination, using: transaction) seal.fulfill(()) @@ -379,4 +379,23 @@ public final class MessageSender : NSObject { tsMessage.update(sendingError: error, transaction: transaction) MessageInvalidator.invalidate(tsMessage, with: transaction) } + + // MARK: Utils + private static func shouldSyncMessage(_ message: Message) -> Bool { + let isNewClosedGroupControlMessage = given(message as? ClosedGroupControlMessage) { + if case .new = $0.kind { + return true + } else { + return false + } } ?? false + let isCallControlMessage = given(message as? CallMessage) { + if case .answer = $0.kind { + return true + } else if case .endCall = $0.kind { + return true + } else { + return false + } } ?? false + return isNewClosedGroupControlMessage || isCallControlMessage || message is ConfigurationMessage || message is UnsendRequest + } }