// // Copyright (c) 2021 Open Whisper Systems. All rights reserved. // import Foundation import SignalRingRTC class GroupCallUpdateMessageHandler: CallServiceObserver, CallObserver, Dependencies { var didSendJoinMessage: Bool = false func sendJoinMessageForCallIfNecessary(_ signalCall: SignalCall) { guard !didSendJoinMessage else { return } guard signalCall.isGroupCall, let groupCall = signalCall.groupCall else { return } guard let eraId = groupCall.peekInfo?.eraId else { return } guard let groupThread = signalCall.thread as? TSGroupThread else { return } guard groupCall.localDeviceState.joinState == .joined else { return } sendUpdateMessageForThread(groupThread, eraId: eraId) didSendJoinMessage = true } func sendLeaveMessageForCallIfNecessary(_ signalCall: SignalCall) { guard didSendJoinMessage else { return } guard signalCall.isGroupCall, let groupCall = signalCall.groupCall else { return } guard let groupThread = signalCall.thread as? TSGroupThread else { return } sendUpdateMessageForThread(groupThread, eraId: groupCall.peekInfo?.eraId) didSendJoinMessage = false } func sendUpdateMessageForThread(_ thread: TSGroupThread, eraId: String?) { Logger.info("Sending call update message for thread \(thread.uniqueId)") let updateMessage = OWSOutgoingGroupCallMessage(thread: thread, eraId: eraId) let messagePreparer = updateMessage.asPreparer SDSDatabaseStorage.shared.asyncWrite { writeTx in Self.messageSenderJobQueue.add(message: messagePreparer, transaction: writeTx) } } func handleUpdateMessage(_ message: SNProtoDataMessageGroupCallUpdate, for thread: TSGroupThread, serverReceivedTimestamp: UInt64) { Logger.info("Received group call update message for thread: \(thread.uniqueId) eraId: \(String(describing: message.eraID))") DispatchQueue.main.async { Self.callService.peekCallAndUpdateThread( thread, expectedEraId: message.eraID, triggerEventTimestamp: serverReceivedTimestamp) } } // MARK: - CallServiceObserver func didUpdateCall(from oldValue: SignalCall?, to newValue: SignalCall?) { if let oldValue = oldValue { sendLeaveMessageForCallIfNecessary(oldValue) } didSendJoinMessage = false oldValue?.removeObserver(self) newValue?.addObserverAndSyncState(observer: self) } // MARK: - CallObserver func groupCallLocalDeviceStateChanged(_ call: SignalCall) { owsAssertDebug(call == Self.callService.currentCall) guard call.isGroupCall, let groupCall = call.groupCall else { return owsFailDebug("Expected a group call") } let isJoined = (groupCall.localDeviceState.joinState == .joined) if isJoined { sendJoinMessageForCallIfNecessary(call) } else { sendLeaveMessageForCallIfNecessary(call) } } func groupCallPeekChanged(_ call: SignalCall) { sendJoinMessageForCallIfNecessary(call) } func groupCallEnded(_ call: SignalCall, reason: GroupCallEndReason) { didSendJoinMessage = false } }