diff --git a/Telegram/NotificationService/Sources/NotificationService.swift b/Telegram/NotificationService/Sources/NotificationService.swift index a3612b311f..87d3a46560 100644 --- a/Telegram/NotificationService/Sources/NotificationService.swift +++ b/Telegram/NotificationService/Sources/NotificationService.swift @@ -961,7 +961,6 @@ private final class NotificationServiceHandler { if let locKey = payloadJson["loc-key"] as? String, (locKey == "CONF_CALL_REQUEST" || locKey == "CONF_CALL_MISSED"), let callIdString = payloadJson["call_id"] as? String { if let callId = Int64(callIdString) { - if let updates = payloadJson["updates"] as? String { var updateString = updates updateString = updateString.replacingOccurrences(of: "-", with: "+") diff --git a/submodules/AccountContext/Sources/PresentationCallManager.swift b/submodules/AccountContext/Sources/PresentationCallManager.swift index 790e705ab4..280a392754 100644 --- a/submodules/AccountContext/Sources/PresentationCallManager.swift +++ b/submodules/AccountContext/Sources/PresentationCallManager.swift @@ -487,6 +487,7 @@ public protocol PresentationGroupCall: AnyObject { func updateTitle(_ title: String) func invitePeer(_ peerId: EnginePeer.Id, isVideo: Bool) -> Bool + func kickPeer(id: EnginePeer.Id) func removedPeer(_ peerId: EnginePeer.Id) var invitedPeers: Signal<[PresentationGroupCallInvitedPeer], NoError> { get } diff --git a/submodules/TelegramCallsUI/Sources/PresentationCall.swift b/submodules/TelegramCallsUI/Sources/PresentationCall.swift index 8d09ee2132..10a083f8b3 100644 --- a/submodules/TelegramCallsUI/Sources/PresentationCall.swift +++ b/submodules/TelegramCallsUI/Sources/PresentationCall.swift @@ -217,6 +217,12 @@ public final class SharedCallAudioContext { } } } + + public func switchToSpeakerIfBuiltin() { + if case .builtin = self.currentAudioOutputValue { + self.setCurrentAudioOutput(.speaker) + } + } } public final class PresentationCallImpl: PresentationCall { @@ -1032,6 +1038,8 @@ public final class PresentationCallImpl: PresentationCall { self.conferenceCallImpl = conferenceCall conferenceCall.upgradedConferenceCall = self + self.sharedAudioContext?.switchToSpeakerIfBuiltin() + for (peerId, isVideo) in self.pendingInviteToConferencePeerIds { let _ = conferenceCall.invitePeer(peerId, isVideo: isVideo) } diff --git a/submodules/TelegramCallsUI/Sources/PresentationGroupCall.swift b/submodules/TelegramCallsUI/Sources/PresentationGroupCall.swift index 7e2325d5da..ce97d819e1 100644 --- a/submodules/TelegramCallsUI/Sources/PresentationGroupCall.swift +++ b/submodules/TelegramCallsUI/Sources/PresentationGroupCall.swift @@ -3986,6 +3986,14 @@ public final class PresentationGroupCallImpl: PresentationGroupCall { } } + public func kickPeer(id: EnginePeer.Id) { + if self.isConference { + self.removedPeer(id) + + self.e2eContext?.kickPeer(id: id) + } + } + public func removedPeer(_ peerId: PeerId) { var updatedInvitedPeers = self.invitedPeersValue updatedInvitedPeers.removeAll(where: { $0.id == peerId}) diff --git a/submodules/TelegramCallsUI/Sources/VideoChatParticipantsComponent.swift b/submodules/TelegramCallsUI/Sources/VideoChatParticipantsComponent.swift index 242d67f9ea..879ebc665e 100644 --- a/submodules/TelegramCallsUI/Sources/VideoChatParticipantsComponent.swift +++ b/submodules/TelegramCallsUI/Sources/VideoChatParticipantsComponent.swift @@ -149,6 +149,7 @@ final class VideoChatParticipantsComponent: Component { let safeInsets: UIEdgeInsets let interfaceOrientation: UIInterfaceOrientation let openParticipantContextMenu: (EnginePeer.Id, ContextExtractedContentContainingView, ContextGesture?) -> Void + let openInvitedParticipantContextMenu: (EnginePeer.Id, ContextExtractedContentContainingView, ContextGesture?) -> Void let updateMainParticipant: (VideoParticipantKey?, Bool?) -> Void let updateIsMainParticipantPinned: (Bool) -> Void let updateIsExpandedUIHidden: (Bool) -> Void @@ -169,6 +170,7 @@ final class VideoChatParticipantsComponent: Component { safeInsets: UIEdgeInsets, interfaceOrientation: UIInterfaceOrientation, openParticipantContextMenu: @escaping (EnginePeer.Id, ContextExtractedContentContainingView, ContextGesture?) -> Void, + openInvitedParticipantContextMenu: @escaping (EnginePeer.Id, ContextExtractedContentContainingView, ContextGesture?) -> Void, updateMainParticipant: @escaping (VideoParticipantKey?, Bool?) -> Void, updateIsMainParticipantPinned: @escaping (Bool) -> Void, updateIsExpandedUIHidden: @escaping (Bool) -> Void, @@ -188,6 +190,7 @@ final class VideoChatParticipantsComponent: Component { self.safeInsets = safeInsets self.interfaceOrientation = interfaceOrientation self.openParticipantContextMenu = openParticipantContextMenu + self.openInvitedParticipantContextMenu = openInvitedParticipantContextMenu self.updateMainParticipant = updateMainParticipant self.updateIsMainParticipantPinned = updateIsMainParticipantPinned self.updateIsExpandedUIHidden = updateIsExpandedUIHidden @@ -1317,8 +1320,18 @@ final class VideoChatParticipantsComponent: Component { inset: 2.0, background: UIColor(white: 0.1, alpha: 1.0) ), - action: nil, - contextAction: nil + action: { [weak self] peer, _, itemView in + guard let self, let component = self.component else { + return + } + component.openInvitedParticipantContextMenu(peer.id, itemView.extractedContainerView, nil) + }, + contextAction: { [weak self] peer, sourceView, gesture in + guard let self, let component = self.component else { + return + } + component.openInvitedParticipantContextMenu(peer.id, sourceView, gesture) + } ) } diff --git a/submodules/TelegramCallsUI/Sources/VideoChatScreen.swift b/submodules/TelegramCallsUI/Sources/VideoChatScreen.swift index 658e2beaa0..4fedb48475 100644 --- a/submodules/TelegramCallsUI/Sources/VideoChatScreen.swift +++ b/submodules/TelegramCallsUI/Sources/VideoChatScreen.swift @@ -2329,6 +2329,12 @@ final class VideoChatScreenComponent: Component { } self.openParticipantContextMenu(id: id, sourceView: sourceView, gesture: gesture) }, + openInvitedParticipantContextMenu: { [weak self] id, sourceView, gesture in + guard let self else { + return + } + self.openInvitedParticipantContextMenu(id: id, sourceView: sourceView, gesture: gesture) + }, updateMainParticipant: { [weak self] key, alsoSetIsUIHidden in guard let self else { return diff --git a/submodules/TelegramCallsUI/Sources/VideoChatScreenParticipantContextMenu.swift b/submodules/TelegramCallsUI/Sources/VideoChatScreenParticipantContextMenu.swift index d34f216387..0161d1a73d 100644 --- a/submodules/TelegramCallsUI/Sources/VideoChatScreenParticipantContextMenu.swift +++ b/submodules/TelegramCallsUI/Sources/VideoChatScreenParticipantContextMenu.swift @@ -299,7 +299,11 @@ extension VideoChatScreenComponent.View { } let _ = groupCall.accountContext.peerChannelMemberCategoriesContextsManager.updateMemberBannedRights(engine: groupCall.accountContext.engine, peerId: callPeerId, memberId: peer.id, bannedRights: TelegramChatBannedRights(flags: [.banReadMessages], untilDate: Int32.max)).start() - groupCall.removedPeer(peer.id) + if groupCall.isConference { + groupCall.kickPeer(id: peer.id) + } else { + groupCall.removedPeer(peer.id) + } self.presentUndoOverlay(content: .banned(text: environment.strings.VoiceChat_RemovedPeerText(EnginePeer(peer).displayTitle(strings: environment.strings, displayOrder: nameDisplayOrder)).string), action: { _ in return false }) })) @@ -347,6 +351,62 @@ extension VideoChatScreenComponent.View { environment.controller()?.presentInGlobalOverlay(contextController) } + func openInvitedParticipantContextMenu(id: EnginePeer.Id, sourceView: ContextExtractedContentContainingView, gesture: ContextGesture?) { + guard let environment = self.environment else { + return + } + guard let currentCall = self.currentCall else { + return + } + guard case .group = self.currentCall else { + return + } + + let itemsForEntry: () -> [ContextMenuItem] = { [weak self] in + guard let self, let environment = self.environment else { + return [] + } + + var items: [ContextMenuItem] = [] + + items.append(.action(ContextMenuActionItem(text: environment.strings.VoiceChat_RemovePeer, textColor: .destructive, icon: { theme in + return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Clear"), color: theme.actionSheet.destructiveActionTextColor) + }, action: { [weak self] c, _ in + c?.dismiss(result: .dismissWithoutContent, completion: nil) + + guard let self else { + return + } + guard case let .group(groupCall) = self.currentCall else { + return + } + + groupCall.kickPeer(id: id) + }))) + return items + } + + let items = itemsForEntry() + + let presentationData = currentCall.accountContext.sharedContext.currentPresentationData.with({ $0 }).withUpdated(theme: environment.theme) + let contextController = ContextController( + presentationData: presentationData, + source: .extracted(ParticipantExtractedContentSource(contentView: sourceView)), + items: .single(ContextController.Items(content: .list(items))), + recognizer: nil, + gesture: gesture + ) + + environment.controller()?.forEachController({ controller in + if let controller = controller as? UndoOverlayController { + controller.dismiss() + } + return true + }) + + environment.controller()?.presentInGlobalOverlay(contextController) + } + private func openAvatarForEditing(fromGallery: Bool = false, completion: @escaping () -> Void = {}) { guard let currentCall = self.currentCall else { return diff --git a/submodules/TelegramCore/Sources/State/ConferenceCallE2EContext.swift b/submodules/TelegramCore/Sources/State/ConferenceCallE2EContext.swift index cb7aa51cb6..367753900a 100644 --- a/submodules/TelegramCore/Sources/State/ConferenceCallE2EContext.swift +++ b/submodules/TelegramCore/Sources/State/ConferenceCallE2EContext.swift @@ -52,6 +52,8 @@ public final class ConferenceCallE2EContext { private var scheduledSynchronizeRemovedParticipantsAfterPoll: Bool = false private var synchronizeRemovedParticipantsDisposable: Disposable? private var synchronizeRemovedParticipantsTimer: Foundation.Timer? + + private var pendingKickPeers: [EnginePeer.Id] = [] init(queue: Queue, engine: TelegramEngine, callId: Int64, accessHash: Int64, userId: Int64, reference: InternalGroupCallReference, state: Atomic, initializeState: @escaping (TelegramKeyPair, Int64, Data) -> ConferenceCallE2EContextState?, keyPair: TelegramKeyPair) { precondition(queue.isCurrent()) @@ -91,37 +93,53 @@ public final class ConferenceCallE2EContext { } func addChainBlocksUpdate(subChainId: Int, blocks: [Data], nextOffset: Int) { - var processBlock = true let updateBaseOffset = nextOffset - blocks.count - if subChainId == 0 { - if let e2ePoll0Offset = self.e2ePoll0Offset { - if e2ePoll0Offset == updateBaseOffset { - self.e2ePoll0Offset = nextOffset - } else if e2ePoll0Offset < updateBaseOffset { - self.e2ePoll(subChainId: subChainId) - } else { - processBlock = false + var blocksToProcess: [Data] = [] + var shouldPoll = false + for i in 0 ..< blocks.count { + let blockOffset = updateBaseOffset + i + if subChainId == 0 { + if var e2ePoll0Offset = self.e2ePoll0Offset { + if blockOffset == e2ePoll0Offset { + e2ePoll0Offset += 1 + self.e2ePoll0Offset = e2ePoll0Offset + blocksToProcess.append(blocks[i]) + } else if blockOffset > e2ePoll0Offset { + shouldPoll = true + } } - } else { - processBlock = false - } - } else if subChainId == 1 { - if let e2ePoll1Offset = self.e2ePoll1Offset { - if e2ePoll1Offset == updateBaseOffset { - self.e2ePoll1Offset = nextOffset - } else if e2ePoll1Offset < updateBaseOffset { - self.e2ePoll(subChainId: subChainId) - } else { - processBlock = false + } else if subChainId == 1 { + if var e2ePoll1Offset = self.e2ePoll1Offset { + if blockOffset == e2ePoll1Offset { + e2ePoll1Offset += 1 + self.e2ePoll1Offset = e2ePoll1Offset + blocksToProcess.append(blocks[i]) + } else if blockOffset > e2ePoll1Offset { + shouldPoll = true + } } - } else { - processBlock = false } - } else { - processBlock = false } - if processBlock { - self.addE2EBlocks(blocks: blocks, subChainId: subChainId) + + if !blocksToProcess.isEmpty { + if subChainId == 0 { + if self.e2ePoll0Disposable != nil { + self.e2ePoll0Disposable?.dispose() + self.e2ePoll0Disposable = nil + shouldPoll = true + } + } else if subChainId == 1 { + if self.e2ePoll1Disposable != nil { + self.e2ePoll1Disposable?.dispose() + self.e2ePoll1Disposable = nil + shouldPoll = true + } + } + self.addE2EBlocks(blocks: blocksToProcess, subChainId: subChainId) + } + + if shouldPoll { + self.e2ePoll(subChainId: subChainId) } } @@ -186,6 +204,14 @@ public final class ConferenceCallE2EContext { guard let self else { return } + + if subChainId == 0 { + self.e2ePoll0Disposable?.dispose() + self.e2ePoll0Disposable = nil + } else if subChainId == 1 { + self.e2ePoll1Disposable?.dispose() + self.e2ePoll1Disposable = nil + } var delayPoll = true if let result { @@ -247,71 +273,139 @@ public final class ConferenceCallE2EContext { let callId = self.callId let accessHash = self.accessHash - self.synchronizeRemovedParticipantsDisposable?.dispose() - self.synchronizeRemovedParticipantsDisposable = (_internal_getGroupCallParticipants( - account: self.engine.account, - reference: self.reference, - offset: "", - ssrcs: [], - limit: 100, - sortAscending: true - ) - |> map(Optional.init) - |> `catch` { _ -> Signal in - return .single(nil) - } - |> mapToSignal { result -> Signal in - guard let result else { - return .single(false) - } - - let blockchainPeerIds = state.with { state -> [Int64] in - guard let state = state.state else { - return [] - } - return state.getParticipantIds() - } - - // Peer ids that are in the blockchain but not in the server list - let removedPeerIds = blockchainPeerIds.filter { blockchainPeerId in - return !result.participants.contains(where: { $0.peer.id.id._internalGetInt64Value() == blockchainPeerId }) - } + if !self.pendingKickPeers.isEmpty { + let pendingKickPeers = self.pendingKickPeers + self.pendingKickPeers.removeAll() - if removedPeerIds.isEmpty { - return .single(false) - } - guard let removeBlock = state.with({ state -> Data? in + self.synchronizeRemovedParticipantsDisposable?.dispose() + + let removeBlock = state.with({ state -> Data? in guard let state = state.state else { return nil } - return state.generateRemoveParticipantsBlock(participantIds: removedPeerIds) - }) else { - return .single(false) - } - - return engine.calls.removeGroupCallBlockchainParticipants(callId: callId, accessHash: accessHash, mode: .cleanup, participantIds: removedPeerIds, block: removeBlock) - |> map { result -> Bool in - switch result { - case .success: - return true - case .pollBlocksAndRetry: - return false + let currentIds = state.getParticipantIds() + let remainingIds = pendingKickPeers.filter({ currentIds.contains($0.id._internalGetInt64Value()) }) + if remainingIds.isEmpty { + return nil + } + + return state.generateRemoveParticipantsBlock(participantIds: remainingIds.map { $0.id._internalGetInt64Value() }) + }) + if let removeBlock { + self.synchronizeRemovedParticipantsDisposable = (engine.calls.removeGroupCallBlockchainParticipants(callId: callId, accessHash: accessHash, mode: .kick, participantIds: pendingKickPeers.map { $0.id._internalGetInt64Value() }, block: removeBlock) + |> map { result -> Bool in + switch result { + case .success: + return true + case .pollBlocksAndRetry: + return false + } + } + |> deliverOnMainQueue).startStrict(next: { [weak self] shouldRetry in + guard let self else { + return + } + + if shouldRetry { + for id in pendingKickPeers { + if !self.pendingKickPeers.contains(id) { + self.pendingKickPeers.append(id) + } + } + } + + self.isSynchronizingRemovedParticipants = false + if self.scheduledSynchronizeRemovedParticipants { + self.scheduledSynchronizeRemovedParticipants = false + self.synchronizeRemovedParticipants() + } else if shouldRetry && !self.scheduledSynchronizeRemovedParticipantsAfterPoll { + self.scheduledSynchronizeRemovedParticipantsAfterPoll = true + self.e2ePoll(subChainId: 0) + } + }) + } else { + self.isSynchronizingRemovedParticipants = false + if self.scheduledSynchronizeRemovedParticipants { + self.scheduledSynchronizeRemovedParticipants = false + self.synchronizeRemovedParticipants() } } + } else { + self.synchronizeRemovedParticipantsDisposable?.dispose() + self.synchronizeRemovedParticipantsDisposable = (_internal_getGroupCallParticipants( + account: self.engine.account, + reference: self.reference, + offset: "", + ssrcs: [], + limit: 100, + sortAscending: true + ) + |> map(Optional.init) + |> `catch` { _ -> Signal in + return .single(nil) + } + |> mapToSignal { result -> Signal in + guard let result else { + return .single(false) + } + + let blockchainPeerIds = state.with { state -> [Int64] in + guard let state = state.state else { + return [] + } + return state.getParticipantIds() + } + + // Peer ids that are in the blockchain but not in the server list + let removedPeerIds = blockchainPeerIds.filter { blockchainPeerId in + return !result.participants.contains(where: { $0.peer.id.id._internalGetInt64Value() == blockchainPeerId }) + } + + if removedPeerIds.isEmpty { + return .single(false) + } + guard let removeBlock = state.with({ state -> Data? in + guard let state = state.state else { + return nil + } + return state.generateRemoveParticipantsBlock(participantIds: removedPeerIds) + }) else { + return .single(false) + } + + return engine.calls.removeGroupCallBlockchainParticipants(callId: callId, accessHash: accessHash, mode: .cleanup, participantIds: removedPeerIds, block: removeBlock) + |> map { result -> Bool in + switch result { + case .success: + return true + case .pollBlocksAndRetry: + return false + } + } + } + |> deliverOn(self.queue)).startStrict(next: { [weak self] shouldRetry in + guard let self else { + return + } + self.isSynchronizingRemovedParticipants = false + if self.scheduledSynchronizeRemovedParticipants { + self.scheduledSynchronizeRemovedParticipants = false + self.synchronizeRemovedParticipants() + } else if shouldRetry && !self.scheduledSynchronizeRemovedParticipantsAfterPoll { + self.scheduledSynchronizeRemovedParticipantsAfterPoll = true + self.e2ePoll(subChainId: 0) + } + }) + } + } + + func kickPeer(id: EnginePeer.Id) { + //TODO:release + if !self.pendingKickPeers.contains(id) { + self.pendingKickPeers.append(id) + + self.synchronizeRemovedParticipants() } - |> deliverOn(self.queue)).startStrict(next: { [weak self] shouldRetry in - guard let self else { - return - } - self.isSynchronizingRemovedParticipants = false - if self.scheduledSynchronizeRemovedParticipants { - self.scheduledSynchronizeRemovedParticipants = false - self.synchronizeRemovedParticipants() - } else if shouldRetry && !self.scheduledSynchronizeRemovedParticipantsAfterPoll { - self.scheduledSynchronizeRemovedParticipantsAfterPoll = true - self.e2ePoll(subChainId: 0) - } - }) } } @@ -349,4 +443,10 @@ public final class ConferenceCallE2EContext { impl.synchronizeRemovedParticipants() } } + + public func kickPeer(id: EnginePeer.Id) { + self.impl.with { impl in + impl.kickPeer(id: id) + } + } } diff --git a/third-party/td/TdBinding/Sources/TdBinding.mm b/third-party/td/TdBinding/Sources/TdBinding.mm index e09decbae0..09ac508a27 100644 --- a/third-party/td/TdBinding/Sources/TdBinding.mm +++ b/third-party/td/TdBinding/Sources/TdBinding.mm @@ -83,6 +83,13 @@ static NSString *hexStringFromData(NSData *data) { if (self != nil) { _callId = callId; _keyPair = keyPair; + + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + #if DEBUG + tde2e_api::set_log_verbosity_level(4); + #endif + }); } return self; } @@ -130,7 +137,17 @@ static NSString *hexStringFromData(NSData *data) { #if DEBUG auto describeResult = tde2e_api::call_describe_message(it); if (describeResult.is_ok()) { - NSLog(@"TdCall.takeOutgoingBroadcastBlocks call_pull_outbound_messages: block %@", [[NSString alloc] initWithBytes:describeResult.value().data() length:describeResult.value().size() encoding:NSUTF8StringEncoding]); + NSString *utf8String = [[NSString alloc] initWithBytes:describeResult.value().data() length:describeResult.value().size() encoding:NSUTF8StringEncoding]; + if (utf8String) { + NSLog(@"TdCall.call_pull_outbound_messages block: %@", utf8String); + } else { + NSString *lossyString = [[NSString alloc] initWithData:[NSData dataWithBytes:describeResult.value().data() length:describeResult.value().size()] encoding:NSASCIIStringEncoding]; + if (lossyString) { + NSLog(@"TdCall.call_pull_outbound_messages block (lossy conversion): %@", lossyString); + } else { + NSLog(@"TdCall.call_pull_outbound_messages block: [binary data, length: %lu]", (unsigned long)describeResult.value().size()); + } + } } else { NSLog(@"TdCall.takeOutgoingBroadcastBlocks call_pull_outbound_messages: describe block failed"); } @@ -178,7 +195,17 @@ static NSString *hexStringFromData(NSData *data) { #if DEBUG auto describeResult = tde2e_api::call_describe_block(mappedBlock); if (describeResult.is_ok()) { - NSLog(@"TdCall.applyBlock block: %@", [[NSString alloc] initWithBytes:describeResult.value().data() length:describeResult.value().size() encoding:NSUTF8StringEncoding]); + NSString *utf8String = [[NSString alloc] initWithBytes:describeResult.value().data() length:describeResult.value().size() encoding:NSUTF8StringEncoding]; + if (utf8String) { + NSLog(@"TdCall.applyBlock block: %@", utf8String); + } else { + NSString *lossyString = [[NSString alloc] initWithData:[NSData dataWithBytes:describeResult.value().data() length:describeResult.value().size()] encoding:NSASCIIStringEncoding]; + if (lossyString) { + NSLog(@"TdCall.applyBlock block (lossy conversion): %@", lossyString); + } else { + NSLog(@"TdCall.applyBlock block: [binary data, length: %lu]", (unsigned long)describeResult.value().size()); + } + } } else { NSLog(@"TdCall.applyBlock block: describe block failed"); } @@ -196,7 +223,17 @@ static NSString *hexStringFromData(NSData *data) { #if DEBUG auto describeResult = tde2e_api::call_describe_message(mappedBlock); if (describeResult.is_ok()) { - NSLog(@"TdCall.applyBroadcastBlock block: %@", [[NSString alloc] initWithBytes:describeResult.value().data() length:describeResult.value().size() encoding:NSUTF8StringEncoding]); + NSString *utf8String = [[NSString alloc] initWithBytes:describeResult.value().data() length:describeResult.value().size() encoding:NSUTF8StringEncoding]; + if (utf8String) { + NSLog(@"TdCall.applyBroadcastBlock block: %@", utf8String); + } else { + NSString *lossyString = [[NSString alloc] initWithData:[NSData dataWithBytes:describeResult.value().data() length:describeResult.value().size()] encoding:NSASCIIStringEncoding]; + if (lossyString) { + NSLog(@"TdCall.applyBroadcastBlock block (lossy conversion): %@", lossyString); + } else { + NSLog(@"TdCall.applyBroadcastBlock block: [binary data, length: %lu]", (unsigned long)describeResult.value().size()); + } + } } else { NSLog(@"TdCall.applyBroadcastBlock block: describe block failed"); } @@ -206,6 +243,23 @@ static NSString *hexStringFromData(NSData *data) { if (!result.is_ok()) { return; } + + describeResult = tde2e_api::call_describe(_callId); + if (describeResult.is_ok()) { + NSString *utf8String = [[NSString alloc] initWithBytes:describeResult.value().data() length:describeResult.value().size() encoding:NSUTF8StringEncoding]; + if (utf8String) { + NSLog(@"TdCall.applyBroadcastBlock call after apply: %@", utf8String); + } else { + NSString *lossyString = [[NSString alloc] initWithData:[NSData dataWithBytes:describeResult.value().data() length:describeResult.value().size()] encoding:NSASCIIStringEncoding]; + if (lossyString) { + NSLog(@"TdCall.applyBroadcastBlock call after apply (lossy conversion): %@", lossyString); + } else { + NSLog(@"TdCall.applyBroadcastBlock call after apply: [binary data, length: %lu]", (unsigned long)describeResult.value().size()); + } + } + } else { + NSLog(@"TdCall.applyBroadcastBlock call after apply: describe block failed"); + } } - (nullable NSData *)generateRemoveParticipantsBlock:(NSArray *)participantIds { diff --git a/third-party/td/build-td-bazel.sh b/third-party/td/build-td-bazel.sh index e4f0c6201c..df4d257c4a 100755 --- a/third-party/td/build-td-bazel.sh +++ b/third-party/td/build-td-bazel.sh @@ -14,7 +14,6 @@ options="" options="$options -DOPENSSL_FOUND=1" options="$options -DOPENSSL_CRYPTO_LIBRARY=${openssl_crypto_library}" options="$options -DOPENSSL_INCLUDE_DIR=${OPENSSL_DIR}/src/include" -#options="$options -DOPENSSL_LIBRARIES=${openssl_crypto_library}" options="$options -DCMAKE_BUILD_TYPE=Release" cd "$BUILD_DIR"