Video call updates

This commit is contained in:
Ali 2020-08-14 13:09:42 +01:00
parent 4c7ad2101d
commit 27ac68e341
6 changed files with 76 additions and 31 deletions

View File

@ -358,6 +358,8 @@ final class CallControllerNode: ViewControllerTracingNode, CallControllerNodePro
private var validLayout: (ContainerViewLayout, CGFloat)?
private var disableActionsUntilTimestamp: Double = 0.0
private var displayedVersionOutdatedAlert: Bool = false
var isMuted: Bool = false {
didSet {
self.buttonsNode.isMuted = self.isMuted
@ -417,9 +419,6 @@ final class CallControllerNode: ViewControllerTracingNode, CallControllerNodePro
self.containerTransformationNode.clipsToBounds = true
self.containerNode = ASDisplayNode()
if self.shouldStayHiddenUntilConnection {
self.containerNode.alpha = 0.0
}
self.imageNode = TransformImageNode()
self.imageNode.contentAnimations = [.subsequentUpdates]
@ -564,7 +563,13 @@ final class CallControllerNode: ViewControllerTracingNode, CallControllerNodePro
self.backButtonNode.addTarget(self, action: #selector(self.backPressed), forControlEvents: .touchUpInside)
if !shouldStayHiddenUntilConnection && call.isVideo && call.isOutgoing {
if shouldStayHiddenUntilConnection {
self.containerNode.alpha = 0.0
Queue.mainQueue().after(3.0, { [weak self] in
self?.containerNode.alpha = 1.0
self?.animateIn()
})
} else if call.isVideo && call.isOutgoing {
self.containerNode.alpha = 0.0
Queue.mainQueue().after(1.0, { [weak self] in
self?.containerNode.alpha = 1.0
@ -881,8 +886,20 @@ final class CallControllerNode: ViewControllerTracingNode, CallControllerNodePro
case .hungUp, .missed:
statusValue = .text(string: self.presentationData.strings.Call_StatusEnded, displayLogo: false)
}
case .error:
statusValue = .text(string: self.presentationData.strings.Call_StatusFailed, displayLogo: false)
case let .error(error):
let text = self.presentationData.strings.Call_StatusFailed
switch error {
case .notSupportedByPeer:
if !self.displayedVersionOutdatedAlert, let peer = self.peer {
self.displayedVersionOutdatedAlert = true
self.present?(textAlertController(sharedContext: self.sharedContext, title: nil, text: self.presentationData.strings.Call_ParticipantVersionOutdatedError(peer.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder)).0, actions: [TextAlertAction(type: .defaultAction, title: self.presentationData.strings.Common_OK, action: {
})]))
}
default:
break
}
statusValue = .text(string: text, displayLogo: false)
}
} else {
statusValue = .text(string: self.presentationData.strings.Call_StatusEnded, displayLogo: false)
@ -1202,6 +1219,7 @@ final class CallControllerNode: ViewControllerTracingNode, CallControllerNodePro
let previewVideoSide = interpolate(from: 350.0, to: 200.0, value: 1.0 - self.pictureInPictureTransitionFraction)
var previewVideoSize = layout.size.aspectFitted(CGSize(width: previewVideoSide, height: previewVideoSide))
previewVideoSize = CGSize(width: 30.0, height: 45.0).aspectFitted(previewVideoSize)
if let minimizedVideoNode = minimizedVideoNode {
switch minimizedVideoNode.currentOrientation {
case .rotation90, .rotation270:
@ -1377,6 +1395,7 @@ final class CallControllerNode: ViewControllerTracingNode, CallControllerNodePro
}
if let expandedVideoNode = self.expandedVideoNode {
transition.updateAlpha(node: expandedVideoNode, alpha: 1.0)
var expandedVideoTransition = transition
if expandedVideoNode.frame.isEmpty || self.disableAnimationForExpandedVideoOnce {
expandedVideoTransition = .immediate
@ -1424,6 +1443,7 @@ final class CallControllerNode: ViewControllerTracingNode, CallControllerNodePro
if let minimizedVideoNode = self.minimizedVideoNode {
transition.updateAlpha(node: minimizedVideoNode, alpha: pipTransitionAlpha)
var minimizedVideoTransition = transition
var didAppear = false
if minimizedVideoNode.frame.isEmpty {

View File

@ -508,7 +508,7 @@ public final class PresentationCallImpl: PresentationCall {
} else {
if self.isVideo {
mappedVideoState = .active
} else if self.isVideoPossible {
} else if self.isVideoPossible && sessionState.isVideoPossible {
mappedVideoState = .inactive
} else {
mappedVideoState = .notAvailable

View File

@ -333,7 +333,7 @@ public final class PresentationCallManagerImpl: PresentationCallManager {
} else {
for (account, _, state, _, _) in ringingStates {
if state.id != self.currentCall?.internalId {
account.callSessionManager.drop(internalId: state.id, reason: .missed, debugLog: .single(nil))
account.callSessionManager.drop(internalId: state.id, reason: .busy, debugLog: .single(nil))
}
}
}

View File

@ -186,6 +186,7 @@ public struct CallSession {
public let isOutgoing: Bool
public let type: CallType
public let state: CallSessionState
public let isVideoPossible: Bool
}
public enum CallSessionConnection: Equatable {
@ -277,7 +278,7 @@ private final class CallSessionContext {
let peerId: PeerId
let isOutgoing: Bool
var type: CallSession.CallType
let isVideoPossible: Bool
var isVideoPossible: Bool
var state: CallSessionInternalState
let subscribers = Bag<(CallSession) -> Void>()
let signalingSubscribers = Bag<(Data) -> Void>()
@ -412,7 +413,7 @@ private final class CallSessionManagerContext {
let index = context.subscribers.add { next in
subscriber.putNext(next)
}
subscriber.putNext(CallSession(id: internalId, isOutgoing: context.isOutgoing, type: context.type, state: CallSessionState(context)))
subscriber.putNext(CallSession(id: internalId, isOutgoing: context.isOutgoing, type: context.type, state: CallSessionState(context), isVideoPossible: context.isVideoPossible))
disposable.set(ActionDisposable {
queue.async {
if let strongSelf = self, let context = strongSelf.contexts[internalId] {
@ -473,7 +474,7 @@ private final class CallSessionManagerContext {
private func contextUpdated(internalId: CallSessionInternalId) {
if let context = self.contexts[internalId] {
let session = CallSession(id: internalId, isOutgoing: context.isOutgoing, type: context.type, state: CallSessionState(context))
let session = CallSession(id: internalId, isOutgoing: context.isOutgoing, type: context.type, state: CallSessionState(context), isVideoPossible: context.isVideoPossible)
for subscriber in context.subscribers.copyItems() {
subscriber(session)
}
@ -526,7 +527,9 @@ private final class CallSessionManagerContext {
wasRinging = true
let internalReason: DropCallSessionReason
switch reason {
case .busy, .hangUp:
case .busy:
internalReason = .busy
case .hangUp:
internalReason = .hangUp(0)
case .disconnect:
internalReason = .disconnect
@ -804,6 +807,9 @@ private final class CallSessionManagerContext {
switch callProtocol {
case let .phoneCallProtocol(_, _, maxLayer, versions):
if !versions.isEmpty {
let isVideoPossible = self.videoVersions().contains(where: { versions.contains($0) })
context.isVideoPossible = isVideoPossible
context.state = .active(id: id, accessHash: accessHash, beginTimestamp: startDate, key: key, keyId: calculatedKeyId, keyVisualHash: keyVisualHash, connections: parseConnectionSet(primary: connections.first!, alternative: Array(connections[1...])), maxLayer: maxLayer, version: versions[0], allowsP2P: allowsP2P)
self.contextUpdated(internalId: internalId)
} else {
@ -820,6 +826,9 @@ private final class CallSessionManagerContext {
switch callProtocol {
case let .phoneCallProtocol(_, _, maxLayer, versions):
if !versions.isEmpty {
let isVideoPossible = self.videoVersions().contains(where: { versions.contains($0) })
context.isVideoPossible = isVideoPossible
context.state = .active(id: id, accessHash: accessHash, beginTimestamp: startDate, key: key, keyId: keyId, keyVisualHash: keyVisualHash, connections: parseConnectionSet(primary: connections.first!, alternative: Array(connections[1...])), maxLayer: maxLayer, version: versions[0], allowsP2P: allowsP2P)
self.contextUpdated(internalId: internalId)
} else {
@ -849,7 +858,7 @@ private final class CallSessionManagerContext {
}
}
if let context = self.contexts[internalId] {
let callSession = CallSession(id: internalId, isOutgoing: context.isOutgoing, type: context.type, state: CallSessionState(context))
let callSession = CallSession(id: internalId, isOutgoing: context.isOutgoing, type: context.type, state: CallSessionState(context), isVideoPossible: context.isVideoPossible)
if let resultRingingStateValue = resultRingingStateValue {
resultRingingState = (resultRingingStateValue, callSession)
}

View File

@ -207,7 +207,6 @@
NSTimeInterval _callPacketTimeout;
std::unique_ptr<tgcalls::Instance> _tgVoip;
OngoingCallThreadLocalContextWebrtcTerminationResult *_terminationResult;
OngoingCallStateWebrtc _state;
OngoingCallVideoStateWebrtc _videoState;
@ -541,29 +540,19 @@ static void (*InternalVoipLoggingFunction)(NSString *) = NULL;
return false;
}
- (void)stopInstanceIfNeeded {
if (!_tgVoip) {
return;
}
tgcalls::FinalState finalState = _tgVoip->stop();
_tgVoip.reset();
_terminationResult = [[OngoingCallThreadLocalContextWebrtcTerminationResult alloc] initWithFinalState:finalState];
}
- (void)beginTermination {
[self stopInstanceIfNeeded];
}
- (void)stop:(void (^)(NSString *, int64_t, int64_t, int64_t, int64_t))completion {
[self stopInstanceIfNeeded];
- (void)stopWithTerminationResult:(OngoingCallThreadLocalContextWebrtcTerminationResult *)terminationResult completion:(void (^)(NSString *, int64_t, int64_t, int64_t, int64_t))completion {
_tgVoip.reset();
if (completion) {
if (_terminationResult) {
NSString *debugLog = [NSString stringWithUTF8String:_terminationResult.finalState.debugLog.c_str()];
_lastDerivedState = [[NSData alloc] initWithBytes:_terminationResult.finalState.persistentState.value.data() length:_terminationResult.finalState.persistentState.value.size()];
if (terminationResult) {
NSString *debugLog = [NSString stringWithUTF8String:terminationResult.finalState.debugLog.c_str()];
_lastDerivedState = [[NSData alloc] initWithBytes:terminationResult.finalState.persistentState.value.data() length:terminationResult.finalState.persistentState.value.size()];
if (completion) {
completion(debugLog, _terminationResult.finalState.trafficStats.bytesSentWifi, _terminationResult.finalState.trafficStats.bytesReceivedWifi, _terminationResult.finalState.trafficStats.bytesSentMobile, _terminationResult.finalState.trafficStats.bytesReceivedMobile);
completion(debugLog, terminationResult.finalState.trafficStats.bytesSentWifi, terminationResult.finalState.trafficStats.bytesReceivedWifi, terminationResult.finalState.trafficStats.bytesSentMobile, terminationResult.finalState.trafficStats.bytesReceivedMobile);
}
} else {
if (completion) {
@ -573,6 +562,33 @@ static void (*InternalVoipLoggingFunction)(NSString *) = NULL;
}
}
- (void)stop:(void (^)(NSString *, int64_t, int64_t, int64_t, int64_t))completion {
if (!_tgVoip) {
return;
}
if (completion == nil) {
_tgVoip->stop([](tgcalls::FinalState finalState) {
});
_tgVoip.reset();
return;
}
__weak OngoingCallThreadLocalContextWebrtc *weakSelf = self;
id<OngoingCallThreadLocalContextQueueWebrtc> queue = _queue;
_tgVoip->stop([weakSelf, queue, completion = [completion copy]](tgcalls::FinalState finalState) {
[queue dispatch:^{
__strong OngoingCallThreadLocalContextWebrtc *strongSelf = weakSelf;
if (!strongSelf) {
return;
}
OngoingCallThreadLocalContextWebrtcTerminationResult *terminationResult = [[OngoingCallThreadLocalContextWebrtcTerminationResult alloc] initWithFinalState:finalState];
[strongSelf stopWithTerminationResult:terminationResult completion:completion];
}];
});
}
- (NSString *)debugInfo {
if (_tgVoip != nullptr) {
NSString *version = [self version];

@ -1 +1 @@
Subproject commit e0e9e3934601c53b542e4cca617bb4050a33792b
Subproject commit a7d9b717fdf7e8e441b47692dc5771684b2d7970