diff --git a/submodules/TelegramCallsUI/Sources/CallKitIntegration.swift b/submodules/TelegramCallsUI/Sources/CallKitIntegration.swift index 3629693c2b..ee37b01142 100644 --- a/submodules/TelegramCallsUI/Sources/CallKitIntegration.swift +++ b/submodules/TelegramCallsUI/Sources/CallKitIntegration.swift @@ -321,6 +321,7 @@ class CallKitProviderDelegate: NSObject, CXProviderDelegate { } func provider(_ provider: CXProvider, didActivate audioSession: AVAudioSession) { + print("provider didActivate default? \(audioSession === AVAudioSession.sharedInstance())") self.audioSessionActivationChanged?(true) self.audioSessionActivePromise?.set(true) } @@ -330,4 +331,3 @@ class CallKitProviderDelegate: NSObject, CXProviderDelegate { self.audioSessionActivePromise?.set(false) } } - diff --git a/submodules/TelegramCallsUI/Sources/PresentationCall.swift b/submodules/TelegramCallsUI/Sources/PresentationCall.swift index e877e21ebb..21640fac09 100644 --- a/submodules/TelegramCallsUI/Sources/PresentationCall.swift +++ b/submodules/TelegramCallsUI/Sources/PresentationCall.swift @@ -437,7 +437,7 @@ public final class PresentationCallImpl: PresentationCall { let audioSessionActive: Signal if let callKitIntegration = strongSelf.callKitIntegration { audioSessionActive = callKitIntegration.audioSessionActive - |> filter { $0 } + /*|> filter { $0 } |> timeout(2.0, queue: Queue.mainQueue(), alternate: Signal { subscriber in if let strongSelf = self, let _ = strongSelf.audioSessionControl { //audioSessionControl.activate({ _ in }) @@ -445,7 +445,7 @@ public final class PresentationCallImpl: PresentationCall { subscriber.putNext(true) subscriber.putCompletion() return EmptyDisposable - }) + })*/ } else { audioSessionControl.activate({ _ in }) audioSessionActive = .single(true) diff --git a/submodules/TelegramVoip/Sources/OngoingCallContext.swift b/submodules/TelegramVoip/Sources/OngoingCallContext.swift index 574dbcb347..776b3d71c2 100644 --- a/submodules/TelegramVoip/Sources/OngoingCallContext.swift +++ b/submodules/TelegramVoip/Sources/OngoingCallContext.swift @@ -326,6 +326,7 @@ private protocol OngoingCallThreadLocalContextProtocol: AnyObject { func nativeVersion() -> String func nativeGetDerivedState() -> Data func addExternalAudioData(data: Data) + func nativeSetIsAudioSessionActive(isActive: Bool) } private final class OngoingCallThreadLocalContextHolder { @@ -381,6 +382,9 @@ extension OngoingCallThreadLocalContext: OngoingCallThreadLocalContextProtocol { func addExternalAudioData(data: Data) { } + + func nativeSetIsAudioSessionActive(isActive: Bool) { + } } public final class OngoingCallVideoCapturer { @@ -573,6 +577,10 @@ extension OngoingCallThreadLocalContextWebrtc: OngoingCallThreadLocalContextProt func addExternalAudioData(data: Data) { self.addExternalAudioData(data) } + + func nativeSetIsAudioSessionActive(isActive: Bool) { + self.setManualAudioSessionIsActive(isActive) + } } private extension OngoingCallContextState.State { @@ -726,6 +734,7 @@ public final class OngoingCallContext { } private let audioSessionDisposable = MetaDisposable() + private let audioSessionActiveDisposable = MetaDisposable() private var networkTypeDisposable: Disposable? public static var maxLayer: Int32 { @@ -950,6 +959,16 @@ public final class OngoingCallContext { self?.audioLevelPromise.set(.single(level)) } + strongSelf.audioSessionActiveDisposable.set((audioSessionActive + |> deliverOn(queue)).start(next: { isActive in + guard let strongSelf = self else { + return + } + strongSelf.withContext { context in + context.nativeSetIsAudioSessionActive(isActive: isActive) + } + })) + strongSelf.networkTypeDisposable = (updatedNetworkType |> deliverOn(queue)).start(next: { networkType in self?.withContext { context in @@ -1010,6 +1029,7 @@ public final class OngoingCallContext { } self.audioSessionDisposable.dispose() + self.audioSessionActiveDisposable.dispose() self.networkTypeDisposable?.dispose() } @@ -1256,6 +1276,8 @@ private final class CallSignalingConnectionImpl: CallSignalingConnection { } func start() { + OngoingCallThreadLocalContextWebrtc.logMessage("CallSignaling: Connecting...") + self.connection.start(queue: self.queue.queue) self.receivePacketHeader() } @@ -1399,48 +1421,91 @@ private final class CallSignalingConnectionImpl: CallSignalingConnection { } private final class CallSignalingConnectionManager { + private final class ConnectionContext { + let connection: CallSignalingConnection + let host: String + let port: UInt16 + + init(connection: CallSignalingConnection, host: String, port: UInt16) { + self.connection = connection + self.host = host + self.port = port + } + } + private let queue: Queue + private let peerTag: Data + private let dataReceived: (Data) -> Void + + private var isRunning: Bool = false private var nextConnectionId: Int = 0 - private var connections: [Int: CallSignalingConnection] = [:] + private var connections: [Int: ConnectionContext] = [:] init(queue: Queue, peerTag: Data, servers: [OngoingCallConnectionDescriptionWebrtc], dataReceived: @escaping (Data) -> Void) { self.queue = queue + self.peerTag = peerTag + self.dataReceived = dataReceived for server in servers { if server.hasTcp { - let id = self.nextConnectionId - self.nextConnectionId += 1 - if #available(iOS 12.0, *) { - let connection = CallSignalingConnectionImpl(queue: queue, host: server.ip, port: UInt16(server.port), peerTag: peerTag, dataReceived: { data in - dataReceived(data) - }, isClosed: { [weak self] in - guard let strongSelf = self else { - return - } - let _ = strongSelf - }) - connections[id] = connection - } + self.spawnConnection(host: server.ip, port: UInt16(server.port)) } } } func start() { + if self.isRunning { + return + } + self.isRunning = true + for (_, connection) in self.connections { - connection.start() + connection.connection.start() } } func stop() { + if !self.isRunning { + return + } + self.isRunning = false + for (_, connection) in self.connections { - connection.stop() + connection.connection.stop() } } func send(payloadData: Data) { for (_, connection) in self.connections { - connection.send(payloadData: payloadData) + connection.connection.send(payloadData: payloadData) + } + } + + private func spawnConnection(host: String, port: UInt16) { + let id = self.nextConnectionId + self.nextConnectionId += 1 + if #available(iOS 12.0, *) { + let dataReceived = self.dataReceived + let connection = CallSignalingConnectionImpl(queue: queue, host: host, port: port, peerTag: self.peerTag, dataReceived: { data in + dataReceived(data) + }, isClosed: { [weak self] in + guard let self else { + return + } + self.handleConnectionFailed(id: id) + }) + self.connections[id] = ConnectionContext(connection: connection, host: host, port: port) + if self.isRunning { + connection.start() + } + } + } + + private func handleConnectionFailed(id: Int) { + if let connection = self.connections.removeValue(forKey: id) { + connection.connection.stop() + self.spawnConnection(host: connection.host, port: connection.port) } } } diff --git a/submodules/TgVoipWebrtc/Sources/OngoingCallThreadLocalContext.mm b/submodules/TgVoipWebrtc/Sources/OngoingCallThreadLocalContext.mm index 636c7248a3..12e0019f94 100644 --- a/submodules/TgVoipWebrtc/Sources/OngoingCallThreadLocalContext.mm +++ b/submodules/TgVoipWebrtc/Sources/OngoingCallThreadLocalContext.mm @@ -28,6 +28,9 @@ #include "platform/darwin/iOS/tgcalls_audio_device_module_ios.h" +#include "platform/darwin/iOS/RTCAudioSession.h" +#include "platform/darwin/iOS/RTCAudioSessionConfiguration.h" + #endif #import "group/GroupInstanceImpl.h" @@ -870,6 +873,7 @@ static void (*InternalVoipLoggingFunction)(NSString *) = NULL; assert([[OngoingCallThreadLocalContextWebrtc versionsWithIncludeReference:true] containsObject:version]); _useManualAudioSessionControl = useManualAudioSessionControl; + [RTCAudioSession sharedInstance].useManualAudio = true; _callReceiveTimeout = 20.0; _callRingTimeout = 90.0; @@ -1115,7 +1119,12 @@ static void (*InternalVoipLoggingFunction)(NSString *) = NULL; - (void)setManualAudioSessionIsActive:(bool)isAudioSessionActive { if (_useManualAudioSessionControl) { - + if (isAudioSessionActive) { + [[RTCAudioSession sharedInstance] audioSessionDidActivate:[AVAudioSession sharedInstance]]; + } else { + [[RTCAudioSession sharedInstance] audioSessionDidDeactivate:[AVAudioSession sharedInstance]]; + } + [RTCAudioSession sharedInstance].isAudioEnabled = isAudioSessionActive; } } diff --git a/submodules/TgVoipWebrtc/tgcalls b/submodules/TgVoipWebrtc/tgcalls index 07b225568f..53bb1711ae 160000 --- a/submodules/TgVoipWebrtc/tgcalls +++ b/submodules/TgVoipWebrtc/tgcalls @@ -1 +1 @@ -Subproject commit 07b225568fb596ba44d472c3fa413da2f8bd3f2e +Subproject commit 53bb1711ae0b3810d34edb1c81982b18d70c5506