Broadcast fixes

This commit is contained in:
Ali 2021-03-09 20:02:56 +04:00
parent bc472b2126
commit 131ca67aff
11 changed files with 108 additions and 73 deletions

View File

@ -61,8 +61,6 @@ final class FFMpegAudioFrameDecoder: MediaTrackFrameDecoder {
} }
return self.delayedFrames.remove(at: minFrameIndex) return self.delayedFrames.remove(at: minFrameIndex)
} }
} else {
assert(true)
} }
return nil return nil

View File

@ -7670,14 +7670,15 @@ public extension Api {
}) })
} }
public static func joinGroupCall(flags: Int32, call: Api.InputGroupCall, joinAs: Api.InputPeer, params: Api.DataJSON) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) { public static func joinGroupCall(flags: Int32, call: Api.InputGroupCall, joinAs: Api.InputPeer, inviteHash: String?, params: Api.DataJSON) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
let buffer = Buffer() let buffer = Buffer()
buffer.appendInt32(909354416) buffer.appendInt32(-1322057861)
serializeInt32(flags, buffer: buffer, boxed: false) serializeInt32(flags, buffer: buffer, boxed: false)
call.serialize(buffer, true) call.serialize(buffer, true)
joinAs.serialize(buffer, true) joinAs.serialize(buffer, true)
if Int(flags) & Int(1 << 1) != 0 {serializeString(inviteHash!, buffer: buffer, boxed: false)}
params.serialize(buffer, true) params.serialize(buffer, true)
return (FunctionDescription(name: "phone.joinGroupCall", parameters: [("flags", flags), ("call", call), ("joinAs", joinAs), ("params", params)]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in return (FunctionDescription(name: "phone.joinGroupCall", parameters: [("flags", flags), ("call", call), ("joinAs", joinAs), ("inviteHash", inviteHash), ("params", params)]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in
let reader = BufferReader(buffer) let reader = BufferReader(buffer)
var result: Api.Updates? var result: Api.Updates?
if let signature = reader.readInt32() { if let signature = reader.readInt32() {
@ -7702,16 +7703,17 @@ public extension Api {
}) })
} }
public static func inviteToGroupCall(call: Api.InputGroupCall, users: [Api.InputUser]) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) { public static func inviteToGroupCall(flags: Int32, call: Api.InputGroupCall, users: [Api.InputUser]) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
let buffer = Buffer() let buffer = Buffer()
buffer.appendInt32(2067345760) buffer.appendInt32(-919505530)
serializeInt32(flags, buffer: buffer, boxed: false)
call.serialize(buffer, true) call.serialize(buffer, true)
buffer.appendInt32(481674261) buffer.appendInt32(481674261)
buffer.appendInt32(Int32(users.count)) buffer.appendInt32(Int32(users.count))
for item in users { for item in users {
item.serialize(buffer, true) item.serialize(buffer, true)
} }
return (FunctionDescription(name: "phone.inviteToGroupCall", parameters: [("call", call), ("users", users)]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in return (FunctionDescription(name: "phone.inviteToGroupCall", parameters: [("flags", flags), ("call", call), ("users", users)]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in
let reader = BufferReader(buffer) let reader = BufferReader(buffer)
var result: Api.Updates? var result: Api.Updates?
if let signature = reader.readInt32() { if let signature = reader.readInt32() {

View File

@ -842,14 +842,7 @@ public final class ManagedAudioSession {
private func updateOutputMode(_ outputMode: AudioSessionOutputMode) { private func updateOutputMode(_ outputMode: AudioSessionOutputMode) {
if let (type, currentOutputMode) = self.currentTypeAndOutputMode, currentOutputMode != outputMode { if let (type, currentOutputMode) = self.currentTypeAndOutputMode, currentOutputMode != outputMode {
//self.currentTypeAndOutputMode = (type, outputMode) self.setup(type: type, outputMode: outputMode, activateNow: true)
do {
try self.setup(type: type, outputMode: outputMode, activateNow: true)
//try self.setupOutputMode(outputMode, type: type)
//try self.activate()
} catch let error {
print("ManagedAudioSession overrideOutputAudioPort error \(error)")
}
} }
} }

View File

@ -352,6 +352,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
private var internalState: InternalState = .requesting private var internalState: InternalState = .requesting
private var callContext: OngoingGroupCallContext? private var callContext: OngoingGroupCallContext?
private var currentConnectionMode: OngoingGroupCallContext.ConnectionMode = .none
private var ssrcMapping: [UInt32: PeerId] = [:] private var ssrcMapping: [UInt32: PeerId] = [:]
private var requestedSsrcs = Set<UInt32>() private var requestedSsrcs = Set<UInt32>()
@ -426,6 +427,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
public var canBeRemoved: Signal<Bool, NoError> { public var canBeRemoved: Signal<Bool, NoError> {
return self._canBeRemoved.get() return self._canBeRemoved.get()
} }
private var markedAsCanBeRemoved = false
private let wasRemoved = Promise<Bool>(false) private let wasRemoved = Promise<Bool>(false)
@ -479,6 +481,15 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
private let isMutedDisposable = MetaDisposable() private let isMutedDisposable = MetaDisposable()
private let memberStatesDisposable = MetaDisposable() private let memberStatesDisposable = MetaDisposable()
private let leaveDisposable = MetaDisposable() private let leaveDisposable = MetaDisposable()
private var isReconnectingAsSpeaker = false {
didSet {
if self.isReconnectingAsSpeaker != oldValue {
self.isReconnectingAsSpeakerPromise.set(self.isReconnectingAsSpeaker)
}
}
}
private let isReconnectingAsSpeakerPromise = ValuePromise<Bool>(false)
private var checkCallDisposable: Disposable? private var checkCallDisposable: Disposable?
private var isCurrentlyConnecting: Bool? private var isCurrentlyConnecting: Bool?
@ -652,13 +663,13 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
if participantUpdate.peerId == strongSelf.joinAsPeerId { if participantUpdate.peerId == strongSelf.joinAsPeerId {
if case let .established(_, _, _, ssrc, _) = strongSelf.internalState, ssrc == participantUpdate.ssrc { if case let .established(_, _, _, ssrc, _) = strongSelf.internalState, ssrc == participantUpdate.ssrc {
strongSelf._canBeRemoved.set(.single(true)) strongSelf.markAsCanBeRemoved()
} }
} }
} else if participantUpdate.peerId == strongSelf.joinAsPeerId { } else if participantUpdate.peerId == strongSelf.joinAsPeerId {
if case let .established(_, connectionMode, _, ssrc, _) = strongSelf.internalState { if case let .established(_, connectionMode, _, ssrc, _) = strongSelf.internalState {
if ssrc != participantUpdate.ssrc { if ssrc != participantUpdate.ssrc {
strongSelf._canBeRemoved.set(.single(true)) strongSelf.markAsCanBeRemoved()
} else if case .broadcast = connectionMode { } else if case .broadcast = connectionMode {
let canUnmute: Bool let canUnmute: Bool
if let muteState = participantUpdate.muteState { if let muteState = participantUpdate.muteState {
@ -668,7 +679,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
} }
if canUnmute { if canUnmute {
strongSelf.requestCall() strongSelf.requestCall(movingFromBroadcastToRtc: true)
} }
} }
} }
@ -682,7 +693,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
} }
case let .call(isTerminated, _, _, _): case let .call(isTerminated, _, _, _):
if isTerminated { if isTerminated {
strongSelf._canBeRemoved.set(.single(true)) strongSelf.markAsCanBeRemoved()
} }
} }
} }
@ -732,7 +743,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
} }
}) })
self.requestCall() self.requestCall(movingFromBroadcastToRtc: false)
} }
deinit { deinit {
@ -922,7 +933,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
return return
} }
if case .established = strongSelf.internalState { if case .established = strongSelf.internalState {
strongSelf.requestCall() strongSelf.requestCall(movingFromBroadcastToRtc: false)
} }
} }
}) })
@ -981,10 +992,12 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
switch joinCallResult.connectionMode { switch joinCallResult.connectionMode {
case .rtc: case .rtc:
strongSelf.callContext?.setConnectionMode(.rtc) strongSelf.currentConnectionMode = .rtc
strongSelf.callContext?.setConnectionMode(.rtc, keepBroadcastConnectedIfWasEnabled: false)
strongSelf.callContext?.setJoinResponse(payload: clientParams, participants: addedParticipants) strongSelf.callContext?.setJoinResponse(payload: clientParams, participants: addedParticipants)
case .broadcast: case .broadcast:
strongSelf.callContext?.setConnectionMode(.broadcast) strongSelf.currentConnectionMode = .broadcast
strongSelf.callContext?.setConnectionMode(.broadcast, keepBroadcastConnectedIfWasEnabled: false)
} }
strongSelf.updateSessionState(internalState: .established(info: joinCallResult.callInfo, connectionMode: joinCallResult.connectionMode, clientParams: clientParams, localSsrc: ssrc, initialState: joinCallResult.state), audioSessionControl: strongSelf.audioSessionControl) strongSelf.updateSessionState(internalState: .established(info: joinCallResult.callInfo, connectionMode: joinCallResult.connectionMode, clientParams: clientParams, localSsrc: ssrc, initialState: joinCallResult.state), audioSessionControl: strongSelf.audioSessionControl)
@ -1004,7 +1017,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
TextAlertAction(type: .genericAction, title: presentationData.strings.Common_OK, action: {}) TextAlertAction(type: .genericAction, title: presentationData.strings.Common_OK, action: {})
]), on: .root, blockInteraction: false, completion: {}) ]), on: .root, blockInteraction: false, completion: {})
} }
strongSelf._canBeRemoved.set(.single(true)) strongSelf.markAsCanBeRemoved()
})) }))
})) }))
@ -1014,12 +1027,12 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
return return
} }
let mappedState: PresentationGroupCallState.NetworkState let mappedState: PresentationGroupCallState.NetworkState
switch state { if state.isConnected {
case .connecting:
mappedState = .connecting
case .connected:
mappedState = .connected mappedState = .connected
} else {
mappedState = .connecting
} }
let wasConnecting = strongSelf.stateValue.networkState == .connecting let wasConnecting = strongSelf.stateValue.networkState == .connecting
if strongSelf.stateValue.networkState != mappedState { if strongSelf.stateValue.networkState != mappedState {
strongSelf.stateValue.networkState = mappedState strongSelf.stateValue.networkState = mappedState
@ -1035,8 +1048,10 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
strongSelf.checkCallDisposable = nil strongSelf.checkCallDisposable = nil
} }
} }
strongSelf.isReconnectingAsSpeaker = state.isTransitioningFromBroadcastToRtc
if (wasConnecting != isConnecting && strongSelf.didConnectOnce) { //|| !strongSelf.didStartConnectingOnce { if (wasConnecting != isConnecting && strongSelf.didConnectOnce) {
if isConnecting { if isConnecting {
let toneRenderer = PresentationCallToneRenderer(tone: .groupConnecting) let toneRenderer = PresentationCallToneRenderer(tone: .groupConnecting)
strongSelf.toneRenderer = toneRenderer strongSelf.toneRenderer = toneRenderer
@ -1050,7 +1065,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
strongSelf.didStartConnectingOnce = true strongSelf.didStartConnectingOnce = true
} }
if case .connected = state { if state.isConnected {
if !strongSelf.didConnectOnce { if !strongSelf.didConnectOnce {
strongSelf.didConnectOnce = true strongSelf.didConnectOnce = true
@ -1176,8 +1191,9 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
participantsContext.activeSpeakers, participantsContext.activeSpeakers,
self.speakingParticipantsContext.get(), self.speakingParticipantsContext.get(),
adminIds, adminIds,
myPeer myPeer,
).start(next: { [weak self] state, activeSpeakers, speakingParticipants, adminIds, myPeer in self.isReconnectingAsSpeakerPromise.get()
).start(next: { [weak self] state, activeSpeakers, speakingParticipants, adminIds, myPeer, isReconnectingAsSpeaker in
guard let strongSelf = self else { guard let strongSelf = self else {
return return
} }
@ -1246,7 +1262,12 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
} }
if participant.peer.id == strongSelf.joinAsPeerId { if participant.peer.id == strongSelf.joinAsPeerId {
if let muteState = participant.muteState { var filteredMuteState = participant.muteState
if isReconnectingAsSpeaker || strongSelf.currentConnectionMode != .rtc {
filteredMuteState = GroupCallParticipantsContext.Participant.MuteState(canUnmute: false, mutedByYou: false)
}
if let muteState = filteredMuteState {
if muteState.canUnmute { if muteState.canUnmute {
switch strongSelf.isMutedValue { switch strongSelf.isMutedValue {
case let .muted(isPushToTalkActive): case let .muted(isPushToTalkActive):
@ -1428,7 +1449,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
return return
} }
strongSelf.checkCallDisposable = nil strongSelf.checkCallDisposable = nil
strongSelf.requestCall() strongSelf.requestCall(movingFromBroadcastToRtc: false)
}) })
} }
} }
@ -1441,6 +1462,11 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
} }
private func markAsCanBeRemoved() { private func markAsCanBeRemoved() {
if self.markedAsCanBeRemoved {
return
}
self.markedAsCanBeRemoved = true
self.callContext?.stop() self.callContext?.stop()
self._canBeRemoved.set(.single(true)) self._canBeRemoved.set(.single(true))
@ -1490,7 +1516,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
strongSelf.stateValue.myPeerId = peerId strongSelf.stateValue.myPeerId = peerId
} }
strongSelf.requestCall() strongSelf.requestCall(movingFromBroadcastToRtc: false)
}) })
} }
@ -1740,8 +1766,9 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
self.participantsContext?.updateShouldBeRecording(shouldBeRecording, title: title) self.participantsContext?.updateShouldBeRecording(shouldBeRecording, title: title)
} }
private func requestCall() { private func requestCall(movingFromBroadcastToRtc: Bool) {
self.callContext?.setConnectionMode(.none) self.currentConnectionMode = .none
self.callContext?.setConnectionMode(.none, keepBroadcastConnectedIfWasEnabled: movingFromBroadcastToRtc)
self.missingSsrcsDisposable.set(nil) self.missingSsrcsDisposable.set(nil)
self.missingSsrcs.removeAll() self.missingSsrcs.removeAll()
@ -1783,8 +1810,10 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
self.checkCallDisposable?.dispose() self.checkCallDisposable?.dispose()
self.checkCallDisposable = nil self.checkCallDisposable = nil
self.stateValue.networkState = .connecting if !movingFromBroadcastToRtc {
self.stateValue.networkState = .connecting
}
self.requestDisposable.set((currentOrRequestedCall self.requestDisposable.set((currentOrRequestedCall
|> deliverOnMainQueue).start(next: { [weak self] value in |> deliverOnMainQueue).start(next: { [weak self] value in
@ -1797,7 +1826,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
strongSelf.updateSessionState(internalState: .active(value), audioSessionControl: strongSelf.audioSessionControl) strongSelf.updateSessionState(internalState: .active(value), audioSessionControl: strongSelf.audioSessionControl)
} else { } else {
strongSelf._canBeRemoved.set(.single(true)) strongSelf.markAsCanBeRemoved()
} }
})) }))
} }

View File

@ -2742,7 +2742,7 @@ public final class VoiceChatController: ViewController {
let memberState: PeerEntry.State let memberState: PeerEntry.State
var memberMuteState: GroupCallParticipantsContext.Participant.MuteState? var memberMuteState: GroupCallParticipantsContext.Participant.MuteState?
if member.raiseHandRating != nil { if member.raiseHandRating != nil || member.hasRaiseHand {
memberState = .raisedHand memberState = .raisedHand
memberMuteState = member.muteState memberMuteState = member.muteState
} else if member.peer.id == self.callState?.myPeerId { } else if member.peer.id == self.callState?.myPeerId {

View File

@ -143,6 +143,7 @@ public func getCurrentGroupCall(account: Account, callId: Int64, accessHash: Int
jsonParams: jsonParams, jsonParams: jsonParams,
joinTimestamp: date, joinTimestamp: date,
raiseHandRating: raiseHandRating, raiseHandRating: raiseHandRating,
hasRaiseHand: raiseHandRating != nil,
activityTimestamp: activeDate.flatMap(Double.init), activityTimestamp: activeDate.flatMap(Double.init),
activityRank: nil, activityRank: nil,
muteState: muteState, muteState: muteState,
@ -310,6 +311,7 @@ public func getGroupCallParticipants(account: Account, callId: Int64, accessHash
jsonParams: jsonParams, jsonParams: jsonParams,
joinTimestamp: date, joinTimestamp: date,
raiseHandRating: raiseHandRating, raiseHandRating: raiseHandRating,
hasRaiseHand: raiseHandRating != nil,
activityTimestamp: activeDate.flatMap(Double.init), activityTimestamp: activeDate.flatMap(Double.init),
activityRank: nil, activityRank: nil,
muteState: muteState, muteState: muteState,
@ -374,7 +376,7 @@ public func joinGroupCall(account: Account, peerId: PeerId, joinAs: PeerId?, cal
flags |= (1 << 0) flags |= (1 << 0)
} }
return account.network.request(Api.functions.phone.joinGroupCall(flags: flags, call: .inputGroupCall(id: callId, accessHash: accessHash), joinAs: inputJoinAs, params: .dataJSON(data: joinPayload))) return account.network.request(Api.functions.phone.joinGroupCall(flags: flags, call: .inputGroupCall(id: callId, accessHash: accessHash), joinAs: inputJoinAs, inviteHash: nil, params: .dataJSON(data: joinPayload)))
|> mapError { error -> JoinGroupCallError in |> mapError { error -> JoinGroupCallError in
if error.errorDescription == "GROUPCALL_ANONYMOUS_FORBIDDEN" { if error.errorDescription == "GROUPCALL_ANONYMOUS_FORBIDDEN" {
return .anonymousNotAllowed return .anonymousNotAllowed
@ -689,6 +691,7 @@ public final class GroupCallParticipantsContext {
public var jsonParams: String? public var jsonParams: String?
public var joinTimestamp: Int32 public var joinTimestamp: Int32
public var raiseHandRating: Int64? public var raiseHandRating: Int64?
public var hasRaiseHand: Bool
public var activityTimestamp: Double? public var activityTimestamp: Double?
public var activityRank: Int? public var activityRank: Int?
public var muteState: MuteState? public var muteState: MuteState?
@ -701,6 +704,7 @@ public final class GroupCallParticipantsContext {
jsonParams: String?, jsonParams: String?,
joinTimestamp: Int32, joinTimestamp: Int32,
raiseHandRating: Int64?, raiseHandRating: Int64?,
hasRaiseHand: Bool,
activityTimestamp: Double?, activityTimestamp: Double?,
activityRank: Int?, activityRank: Int?,
muteState: MuteState?, muteState: MuteState?,
@ -712,6 +716,7 @@ public final class GroupCallParticipantsContext {
self.jsonParams = jsonParams self.jsonParams = jsonParams
self.joinTimestamp = joinTimestamp self.joinTimestamp = joinTimestamp
self.raiseHandRating = raiseHandRating self.raiseHandRating = raiseHandRating
self.hasRaiseHand = hasRaiseHand
self.activityTimestamp = activityTimestamp self.activityTimestamp = activityTimestamp
self.activityRank = activityRank self.activityRank = activityRank
self.muteState = muteState self.muteState = muteState
@ -737,6 +742,9 @@ public final class GroupCallParticipantsContext {
if lhs.raiseHandRating != rhs.raiseHandRating { if lhs.raiseHandRating != rhs.raiseHandRating {
return false return false
} }
if lhs.hasRaiseHand != rhs.hasRaiseHand {
return false
}
if lhs.activityTimestamp != rhs.activityTimestamp { if lhs.activityTimestamp != rhs.activityTimestamp {
return false return false
} }
@ -948,17 +956,27 @@ public final class GroupCallParticipantsContext {
public var immediateState: State? public var immediateState: State?
public var state: Signal<State, NoError> { public var state: Signal<State, NoError> {
let accountPeerId = self.account.peerId
return self.statePromise.get() return self.statePromise.get()
|> map { state -> State in |> map { state -> State in
if state.overlayState.isEmpty { if state.overlayState.isEmpty {
return state.state return state.state
} }
var publicState = state.state var publicState = state.state
var sortAgain = false
let canSeeHands = state.state.isCreator || state.state.adminIds.contains(accountPeerId)
for i in 0 ..< publicState.participants.count { for i in 0 ..< publicState.participants.count {
if let pendingMuteState = state.overlayState.pendingMuteStateChanges[publicState.participants[i].peer.id] { if let pendingMuteState = state.overlayState.pendingMuteStateChanges[publicState.participants[i].peer.id] {
publicState.participants[i].muteState = pendingMuteState.state publicState.participants[i].muteState = pendingMuteState.state
publicState.participants[i].volume = pendingMuteState.volume publicState.participants[i].volume = pendingMuteState.volume
} }
if !canSeeHands && publicState.participants[i].raiseHandRating != nil {
publicState.participants[i].raiseHandRating = nil
sortAgain = true
}
}
if sortAgain {
publicState.participants.sort()
} }
return publicState return publicState
} }
@ -1364,6 +1382,7 @@ public final class GroupCallParticipantsContext {
jsonParams: participantUpdate.jsonParams, jsonParams: participantUpdate.jsonParams,
joinTimestamp: participantUpdate.joinTimestamp, joinTimestamp: participantUpdate.joinTimestamp,
raiseHandRating: participantUpdate.raiseHandRating, raiseHandRating: participantUpdate.raiseHandRating,
hasRaiseHand: participantUpdate.raiseHandRating != nil,
activityTimestamp: activityTimestamp, activityTimestamp: activityTimestamp,
activityRank: previousActivityRank, activityRank: previousActivityRank,
muteState: participantUpdate.muteState, muteState: participantUpdate.muteState,
@ -1749,7 +1768,7 @@ public func inviteToGroupCall(account: Account, callId: Int64, accessHash: Int64
return .fail(.generic) return .fail(.generic)
} }
return account.network.request(Api.functions.phone.inviteToGroupCall(call: .inputGroupCall(id: callId, accessHash: accessHash), users: [apiUser])) return account.network.request(Api.functions.phone.inviteToGroupCall(flags: 0, call: .inputGroupCall(id: callId, accessHash: accessHash), users: [apiUser]))
|> mapError { _ -> InviteToGroupCallError in |> mapError { _ -> InviteToGroupCallError in
return .generic return .generic
} }

View File

@ -134,9 +134,9 @@ public final class OngoingGroupCallContext {
case broadcast case broadcast
} }
public enum NetworkState { public struct NetworkState: Equatable {
case connecting public var isConnected: Bool
case connected public var isTransitioningFromBroadcastToRtc: Bool
} }
public enum AudioLevelKey: Hashable { public enum AudioLevelKey: Hashable {
@ -151,7 +151,7 @@ public final class OngoingGroupCallContext {
let sessionId = UInt32.random(in: 0 ..< UInt32(Int32.max)) let sessionId = UInt32.random(in: 0 ..< UInt32(Int32.max))
let joinPayload = Promise<(String, UInt32)>() let joinPayload = Promise<(String, UInt32)>()
let networkState = ValuePromise<NetworkState>(.connecting, ignoreRepeated: true) let networkState = ValuePromise<NetworkState>(NetworkState(isConnected: false, isTransitioningFromBroadcastToRtc: false), ignoreRepeated: true)
let isMuted = ValuePromise<Bool>(true, ignoreRepeated: true) let isMuted = ValuePromise<Bool>(true, ignoreRepeated: true)
let audioLevels = ValuePipe<[(AudioLevelKey, Float, Bool)]>() let audioLevels = ValuePipe<[(AudioLevelKey, Float, Bool)]>()
@ -210,16 +210,7 @@ public final class OngoingGroupCallContext {
guard let strongSelf = self else { guard let strongSelf = self else {
return return
} }
let mappedState: NetworkState strongSelf.networkState.set(NetworkState(isConnected: state.isConnected, isTransitioningFromBroadcastToRtc: state.isTransitioningFromBroadcastToRtc))
switch state {
case .connecting:
mappedState = .connecting
case .connected:
mappedState = .connected
@unknown default:
mappedState = .connecting
}
strongSelf.networkState.set(mappedState)
} }
} }
@ -295,7 +286,7 @@ public final class OngoingGroupCallContext {
self.context.stop() self.context.stop()
} }
func setConnectionMode(_ connectionMode: ConnectionMode) { func setConnectionMode(_ connectionMode: ConnectionMode, keepBroadcastConnectedIfWasEnabled: Bool) {
let mappedConnectionMode: OngoingCallConnectionMode let mappedConnectionMode: OngoingCallConnectionMode
switch connectionMode { switch connectionMode {
case .none: case .none:
@ -305,7 +296,7 @@ public final class OngoingGroupCallContext {
case .broadcast: case .broadcast:
mappedConnectionMode = .broadcast mappedConnectionMode = .broadcast
} }
self.context.setConnectionMode(mappedConnectionMode) self.context.setConnectionMode(mappedConnectionMode, keepBroadcastConnectedIfWasEnabled: keepBroadcastConnectedIfWasEnabled)
if (mappedConnectionMode != .rtc) { if (mappedConnectionMode != .rtc) {
self.joinPayload.set(.never()) self.joinPayload.set(.never())
@ -504,9 +495,9 @@ public final class OngoingGroupCallContext {
}) })
} }
public func setConnectionMode(_ connectionMode: ConnectionMode) { public func setConnectionMode(_ connectionMode: ConnectionMode, keepBroadcastConnectedIfWasEnabled: Bool) {
self.impl.with { impl in self.impl.with { impl in
impl.setConnectionMode(connectionMode) impl.setConnectionMode(connectionMode, keepBroadcastConnectedIfWasEnabled: keepBroadcastConnectedIfWasEnabled)
} }
} }

View File

@ -151,10 +151,10 @@ typedef NS_ENUM(int32_t, OngoingCallDataSavingWebrtc) {
- (void)switchAudioInput:(NSString * _Nonnull)deviceId; - (void)switchAudioInput:(NSString * _Nonnull)deviceId;
@end @end
typedef NS_ENUM(int32_t, GroupCallNetworkState) { typedef struct {
GroupCallNetworkStateConnecting, bool isConnected;
GroupCallNetworkStateConnected bool isTransitioningFromBroadcastToRtc;
}; } GroupCallNetworkState;
@interface OngoingGroupCallParticipantDescription : NSObject @interface OngoingGroupCallParticipantDescription : NSObject
@ -200,7 +200,7 @@ typedef NS_ENUM(int32_t, OngoingGroupCallBroadcastPartStatus) {
- (void)stop; - (void)stop;
- (void)setConnectionMode:(OngoingCallConnectionMode)connectionMode; - (void)setConnectionMode:(OngoingCallConnectionMode)connectionMode keepBroadcastConnectedIfWasEnabled:(bool)keepBroadcastConnectedIfWasEnabled;
- (void)emitJoinPayload:(void (^ _Nonnull)(NSString * _Nonnull, uint32_t))completion; - (void)emitJoinPayload:(void (^ _Nonnull)(NSString * _Nonnull, uint32_t))completion;
- (void)setJoinResponsePayload:(NSString * _Nonnull)payload participants:(NSArray<OngoingGroupCallParticipantDescription *> * _Nonnull)participants; - (void)setJoinResponsePayload:(NSString * _Nonnull)payload participants:(NSArray<OngoingGroupCallParticipantDescription *> * _Nonnull)participants;

View File

@ -863,13 +863,16 @@ private:
__weak GroupCallThreadLocalContext *weakSelf = self; __weak GroupCallThreadLocalContext *weakSelf = self;
_instance.reset(new tgcalls::GroupInstanceCustomImpl((tgcalls::GroupInstanceDescriptor){ _instance.reset(new tgcalls::GroupInstanceCustomImpl((tgcalls::GroupInstanceDescriptor){
.networkStateUpdated = [weakSelf, queue, networkStateUpdated](bool isConnected) { .networkStateUpdated = [weakSelf, queue, networkStateUpdated](tgcalls::GroupNetworkState networkState) {
[queue dispatch:^{ [queue dispatch:^{
__strong GroupCallThreadLocalContext *strongSelf = weakSelf; __strong GroupCallThreadLocalContext *strongSelf = weakSelf;
if (strongSelf == nil) { if (strongSelf == nil) {
return; return;
} }
networkStateUpdated(isConnected ? GroupCallNetworkStateConnected : GroupCallNetworkStateConnecting); GroupCallNetworkState mappedState;
mappedState.isConnected = networkState.isConnected;
mappedState.isTransitioningFromBroadcastToRtc = networkState.isTransitioningFromBroadcastToRtc;
networkStateUpdated(mappedState);
}]; }];
}, },
.audioLevelsUpdated = [audioLevelsUpdated](tgcalls::GroupLevelsUpdate const &levels) { .audioLevelsUpdated = [audioLevelsUpdated](tgcalls::GroupLevelsUpdate const &levels) {
@ -1041,7 +1044,7 @@ static void processJoinPayload(tgcalls::GroupJoinPayload &payload, void (^ _Nonn
completion(string, payload.ssrc); completion(string, payload.ssrc);
} }
- (void)setConnectionMode:(OngoingCallConnectionMode)connectionMode { - (void)setConnectionMode:(OngoingCallConnectionMode)connectionMode keepBroadcastConnectedIfWasEnabled:(bool)keepBroadcastConnectedIfWasEnabled {
if (_instance) { if (_instance) {
tgcalls::GroupConnectionMode mappedConnectionMode; tgcalls::GroupConnectionMode mappedConnectionMode;
switch (connectionMode) { switch (connectionMode) {
@ -1062,7 +1065,7 @@ static void processJoinPayload(tgcalls::GroupJoinPayload &payload, void (^ _Nonn
break; break;
} }
} }
_instance->setConnectionMode(mappedConnectionMode); _instance->setConnectionMode(mappedConnectionMode, keepBroadcastConnectedIfWasEnabled);
} }
} }

@ -1 +1 @@
Subproject commit 18ed939bf6818139f7147cde1c34cf22eb5080a2 Subproject commit d19c74b1474e4aab01d797373f1d62e4da5f87a5

View File

@ -1,5 +1,5 @@
{ {
"app": "7.5.1", "app": "7.6",
"bazel": "4.0.0", "bazel": "4.0.0",
"xcode": "12.4" "xcode": "12.4"
} }