refactor on call ending

pull/1061/head
Ryan ZHAO 3 months ago
parent 03eec6ae5a
commit 1fee262ee4

@ -305,15 +305,16 @@ public final class SessionCall: CurrentCallProtocol, WebRTCSessionDelegate {
func endSessionCall() { func endSessionCall() {
guard !hasEnded else { return } guard !hasEnded else { return }
let sessionId: String = self.sessionId
webRTCSession.hangUp() webRTCSession.hangUp()
webRTCSession.endCall(
Storage.shared.writeAsync { [weak self] db in with: self.sessionId
try self?.webRTCSession.endCall(db, with: sessionId) )
} .sinkUntilComplete(
receiveCompletion: { [weak self] _ in
hasEnded = true self?.hasEnded = true
Singleton.callManager.cleanUpPreviousCall()
}
)
} }
func handleCallInitializationFailed() { func handleCallInitializationFailed() {

@ -143,20 +143,8 @@ public final class SessionCallManager: NSObject, CallManagerProtocol {
return return
} }
func handleCallEnded() {
SNLog("[Calls] Call ended.")
WebRTCSession.current = nil
UserDefaults.sharedLokiProject?[.isCallOngoing] = false
UserDefaults.sharedLokiProject?[.lastCallPreOffer] = nil
if Singleton.hasAppContext && Singleton.appContext.isNotInForeground {
(UIApplication.shared.delegate as? AppDelegate)?.stopPollers()
Log.flush()
}
}
guard let call = currentCall else { guard let call = currentCall else {
handleCallEnded() self.cleanUpPreviousCall()
suspendDatabaseIfCallEndedInBackground() suspendDatabaseIfCallEndedInBackground()
return return
} }
@ -175,9 +163,7 @@ public final class SessionCallManager: NSObject, CallManagerProtocol {
call.updateCallMessage(mode: .local, using: dependencies) call.updateCallMessage(mode: .local, using: dependencies)
} }
(call as? SessionCall)?.webRTCSession.dropConnection() self.cleanUpPreviousCall()
self.currentCall = nil
handleCallEnded()
} }
public func currentWebRTCSessionMatches(callId: String) -> Bool { public func currentWebRTCSessionMatches(callId: String) -> Bool {
@ -301,4 +287,19 @@ public final class SessionCallManager: NSObject, CallManagerProtocol {
(Singleton.appContext.frontmostViewController as? CallVC)?.handleEndCallMessage() (Singleton.appContext.frontmostViewController as? CallVC)?.handleEndCallMessage()
MiniCallView.current?.dismiss() MiniCallView.current?.dismiss()
} }
public func cleanUpPreviousCall() {
SNLog("[Calls] Clean up calls")
WebRTCSession.current?.dropConnection()
WebRTCSession.current = nil
currentCall = nil
UserDefaults.sharedLokiProject?[.isCallOngoing] = false
UserDefaults.sharedLokiProject?[.lastCallPreOffer] = nil
if Singleton.hasAppContext && Singleton.appContext.isNotInForeground {
(UIApplication.shared.delegate as? AppDelegate)?.stopPollers()
Log.flush()
}
}
} }

@ -358,39 +358,50 @@ public final class WebRTCSession : NSObject, RTCPeerConnectionDelegate {
) )
} }
public func endCall( public func endCall(with sessionId: String) -> AnyPublisher<Void, Error> {
_ db: Database, return dependencies.storage
with sessionId: String .writePublisher { [dependencies = self.dependencies] db in
) throws { guard let thread: SessionThread = try SessionThread.fetchOne(db, id: sessionId) else {
guard let thread: SessionThread = try SessionThread.fetchOne(db, id: sessionId) else { return } throw WebRTCSessionError.noThread
}
SNLog("[Calls] Sending end call message.")
SNLog("[Calls] Sending end call message.")
let preparedSendData: MessageSender.PreparedSendData = try MessageSender
.preparedSendData( return try MessageSender
db, .preparedSendData(
message: CallMessage( db,
uuid: self.uuid, message: CallMessage(
kind: .endCall, uuid: self.uuid,
sdps: [] kind: .endCall,
) sdps: []
.with(try? thread.disappearingMessagesConfiguration )
.fetchOne(db)? .with(try? thread.disappearingMessagesConfiguration
.forcedWithDisappearAfterReadIfNeeded() .fetchOne(db)?
), .forcedWithDisappearAfterReadIfNeeded()
to: try Message.Destination.from(db, threadId: thread.id, threadVariant: thread.variant), ),
namespace: try Message.Destination to: try Message.Destination.from(db, threadId: thread.id, threadVariant: thread.variant),
.from(db, threadId: thread.id, threadVariant: thread.variant) namespace: try Message.Destination
.defaultNamespace, .from(db, threadId: thread.id, threadVariant: thread.variant)
interactionId: nil, .defaultNamespace,
using: dependencies interactionId: nil,
) using: dependencies
)
MessageSender }
.sendImmediate(data: preparedSendData, using: dependencies)
.subscribe(on: DispatchQueue.global(qos: .userInitiated)) .subscribe(on: DispatchQueue.global(qos: .userInitiated))
.retry(5) .flatMap { [dependencies = self.dependencies] sendData in
.sinkUntilComplete() MessageSender
.sendImmediate(data: sendData, using: dependencies)
.retry(5)
}
.handleEvents(receiveCompletion: { result in
switch result {
case .finished:
SNLog("[Calls] End call message sent")
case .failure(let error):
SNLog("[Calls] Error sending End call message due to error: \(error)")
}
})
.eraseToAnyPublisher()
} }
public func dropConnection() { public func dropConnection() {

@ -38,4 +38,5 @@ public protocol CallManagerProtocol {
func currentWebRTCSessionMatches(callId: String) -> Bool func currentWebRTCSessionMatches(callId: String) -> Bool
func dismissAllCallUI() func dismissAllCallUI()
func cleanUpPreviousCall()
} }

@ -23,4 +23,5 @@ internal struct NoopSessionCallManager: CallManagerProtocol {
func currentWebRTCSessionMatches(callId: String) -> Bool { return false } func currentWebRTCSessionMatches(callId: String) -> Bool { return false }
func dismissAllCallUI() {} func dismissAllCallUI() {}
func cleanUpPreviousCall() {}
} }

@ -38,7 +38,7 @@ extension MessageReceiver {
// MARK: - Specific Handling // MARK: - Specific Handling
private static func handleNewCallMessage(_ db: Database, message: CallMessage, using dependencies: Dependencies) throws { private static func handleNewCallMessage(_ db: Database, message: CallMessage, using dependencies: Dependencies) throws {
SNLog("[Calls] Received pre-offer message.") SNLog("[Calls] Received pre-offer message with uuid: \(message.uuid).")
// Determine whether the app is active based on the prefs rather than the UIApplication state to avoid // Determine whether the app is active based on the prefs rather than the UIApplication state to avoid
// requiring main-thread execution // requiring main-thread execution
@ -59,6 +59,7 @@ extension MessageReceiver {
else { return } else { return }
guard let timestamp = message.sentTimestamp, TimestampUtils.isWithinOneMinute(timestampMs: timestamp) else { guard let timestamp = message.sentTimestamp, TimestampUtils.isWithinOneMinute(timestampMs: timestamp) else {
// Add missed call message for call offer messages from more than one minute // Add missed call message for call offer messages from more than one minute
SNLog("[Calls] Got an expired call offer message with uuid: \(message.uuid). Sent at \(message.sentTimestamp), now is \(Date().timeIntervalSince1970 * 1000)")
if let interaction: Interaction = try MessageReceiver.insertCallInfoMessage(db, for: message, state: .missed, using: dependencies) { if let interaction: Interaction = try MessageReceiver.insertCallInfoMessage(db, for: message, state: .missed, using: dependencies) {
let thread: SessionThread = try SessionThread.upsert( let thread: SessionThread = try SessionThread.upsert(
db, db,

Loading…
Cancel
Save