Fix simultaneous calls

This commit is contained in:
Ali 2020-11-30 03:05:43 +04:00
parent 454b01aab5
commit e27732b826
2 changed files with 57 additions and 12 deletions

View File

@ -60,6 +60,7 @@ public final class PresentationCallManagerImpl: PresentationCallManager {
} }
private var currentCallDisposable = MetaDisposable() private var currentCallDisposable = MetaDisposable()
private let removeCurrentCallDisposable = MetaDisposable() private let removeCurrentCallDisposable = MetaDisposable()
private let removeCurrentGroupCallDisposable = MetaDisposable()
private var currentGroupCallValue: PresentationGroupCallImpl? private var currentGroupCallValue: PresentationGroupCallImpl?
private var currentGroupCall: PresentationGroupCallImpl? { private var currentGroupCall: PresentationGroupCallImpl? {
@ -68,9 +69,17 @@ public final class PresentationCallManagerImpl: PresentationCallManager {
private var ringingStatesDisposable: Disposable? private var ringingStatesDisposable: Disposable?
private let hasActiveCallsPromise = ValuePromise<Bool>(false, ignoreRepeated: true) private let hasActivePersonalCallsPromise = ValuePromise<Bool>(false, ignoreRepeated: true)
private let hasActiveGroupCallsPromise = ValuePromise<Bool>(false, ignoreRepeated: true)
public var hasActiveCalls: Signal<Bool, NoError> { public var hasActiveCalls: Signal<Bool, NoError> {
return self.hasActiveCallsPromise.get() return combineLatest(queue: .mainQueue(),
self.hasActivePersonalCallsPromise.get(),
self.hasActiveGroupCallsPromise.get()
)
|> map { value1, value2 -> Bool in
return value1 || value2
}
|> distinctUntilChanged
} }
private let currentCallPromise = Promise<PresentationCall?>(nil) private let currentCallPromise = Promise<PresentationCall?>(nil)
@ -254,6 +263,7 @@ public final class PresentationCallManagerImpl: PresentationCallManager {
self.currentCallDisposable.dispose() self.currentCallDisposable.dispose()
self.ringingStatesDisposable?.dispose() self.ringingStatesDisposable?.dispose()
self.removeCurrentCallDisposable.dispose() self.removeCurrentCallDisposable.dispose()
self.removeCurrentGroupCallDisposable.dispose()
self.startCallDisposable.dispose() self.startCallDisposable.dispose()
self.proxyServerDisposable?.dispose() self.proxyServerDisposable?.dispose()
self.callSettingsDisposable?.dispose() self.callSettingsDisposable?.dispose()
@ -300,14 +310,14 @@ public final class PresentationCallManagerImpl: PresentationCallManager {
) )
strongSelf.updateCurrentCall(call) strongSelf.updateCurrentCall(call)
strongSelf.currentCallPromise.set(.single(call)) strongSelf.currentCallPromise.set(.single(call))
strongSelf.hasActiveCallsPromise.set(true) strongSelf.hasActivePersonalCallsPromise.set(true)
strongSelf.removeCurrentCallDisposable.set((call.canBeRemoved strongSelf.removeCurrentCallDisposable.set((call.canBeRemoved
|> deliverOnMainQueue).start(next: { [weak self, weak call] value in |> deliverOnMainQueue).start(next: { [weak self, weak call] value in
if value, let strongSelf = self, let call = call { if value, let strongSelf = self, let call = call {
if strongSelf.currentCall === call { if strongSelf.currentCall === call {
strongSelf.updateCurrentCall(nil) strongSelf.updateCurrentCall(nil)
strongSelf.currentCallPromise.set(.single(nil)) strongSelf.currentCallPromise.set(.single(nil))
strongSelf.hasActiveCallsPromise.set(false) strongSelf.hasActivePersonalCallsPromise.set(false)
} }
} }
})) }))
@ -331,6 +341,9 @@ public final class PresentationCallManagerImpl: PresentationCallManager {
if let call = self.currentCall { if let call = self.currentCall {
alreadyInCall = true alreadyInCall = true
alreadyInCallWithPeerId = call.peerId alreadyInCallWithPeerId = call.peerId
} else if let currentGroupCall = self.currentGroupCallValue {
alreadyInCall = true
alreadyInCallWithPeerId = currentGroupCall.peerId
} else { } else {
if #available(iOS 10.0, *) { if #available(iOS 10.0, *) {
if CXCallObserver().calls.contains(where: { $0.hasEnded == false }) { if CXCallObserver().calls.contains(where: { $0.hasEnded == false }) {
@ -395,6 +408,13 @@ public final class PresentationCallManagerImpl: PresentationCallManager {
|> deliverOnMainQueue).start(next: { _ in |> deliverOnMainQueue).start(next: { _ in
begin() begin()
})) }))
} else if let currentGroupCall = self.currentGroupCallValue {
self.startCallDisposable.set((currentGroupCall.leave(terminateIfPossible: false)
|> filter { $0 }
|> take(1)
|> deliverOnMainQueue).start(next: { _ in
begin()
}))
} else { } else {
begin() begin()
} }
@ -410,6 +430,13 @@ public final class PresentationCallManagerImpl: PresentationCallManager {
|> deliverOnMainQueue).start(next: { _ in |> deliverOnMainQueue).start(next: { _ in
begin() begin()
})) }))
} else if let currentGroupCall = self.currentGroupCallValue {
self.startCallDisposable.set((currentGroupCall.leave(terminateIfPossible: false)
|> filter { $0 }
|> take(1)
|> deliverOnMainQueue).start(next: { _ in
begin()
}))
} else { } else {
begin() begin()
} }
@ -544,14 +571,14 @@ public final class PresentationCallManagerImpl: PresentationCallManager {
) )
strongSelf.updateCurrentCall(call) strongSelf.updateCurrentCall(call)
strongSelf.currentCallPromise.set(.single(call)) strongSelf.currentCallPromise.set(.single(call))
strongSelf.hasActiveCallsPromise.set(true) strongSelf.hasActivePersonalCallsPromise.set(true)
strongSelf.removeCurrentCallDisposable.set((call.canBeRemoved strongSelf.removeCurrentCallDisposable.set((call.canBeRemoved
|> deliverOnMainQueue).start(next: { [weak call] value in |> deliverOnMainQueue).start(next: { [weak call] value in
if value, let strongSelf = self, let call = call { if value, let strongSelf = self, let call = call {
if strongSelf.currentCall === call { if strongSelf.currentCall === call {
strongSelf.updateCurrentCall(nil) strongSelf.updateCurrentCall(nil)
strongSelf.currentCallPromise.set(.single(nil)) strongSelf.currentCallPromise.set(.single(nil))
strongSelf.hasActiveCallsPromise.set(false) strongSelf.hasActivePersonalCallsPromise.set(false)
} }
} }
})) }))
@ -597,6 +624,7 @@ public final class PresentationCallManagerImpl: PresentationCallManager {
let begin: () -> Void = { [weak self] in let begin: () -> Void = { [weak self] in
let _ = self?.startGroupCall(accountContext: context, peerId: peerId, initialCall: initialCall, sourcePanel: sourcePanel).start() let _ = self?.startGroupCall(accountContext: context, peerId: peerId, initialCall: initialCall, sourcePanel: sourcePanel).start()
} }
if let currentGroupCall = self.currentGroupCallValue { if let currentGroupCall = self.currentGroupCallValue {
if endCurrentIfAny { if endCurrentIfAny {
let endSignal = currentGroupCall.leave(terminateIfPossible: false) let endSignal = currentGroupCall.leave(terminateIfPossible: false)
@ -609,6 +637,16 @@ public final class PresentationCallManagerImpl: PresentationCallManager {
} else { } else {
return .alreadyInProgress(currentGroupCall.peerId) return .alreadyInProgress(currentGroupCall.peerId)
} }
} else if let currentCall = self.currentCall {
if endCurrentIfAny {
self.callKitIntegration?.dropCall(uuid: currentCall.internalId)
self.startCallDisposable.set((currentCall.hangUp()
|> deliverOnMainQueue).start(next: { _ in
begin()
}))
} else {
return .alreadyInProgress(currentCall.peerId)
}
} else { } else {
begin() begin()
} }
@ -674,14 +712,19 @@ public final class PresentationCallManagerImpl: PresentationCallManager {
call.sourcePanel = sourcePanel call.sourcePanel = sourcePanel
strongSelf.updateCurrentGroupCall(call) strongSelf.updateCurrentGroupCall(call)
strongSelf.currentGroupCallPromise.set(.single(call)) strongSelf.currentGroupCallPromise.set(.single(call))
strongSelf.hasActiveCallsPromise.set(true) strongSelf.hasActiveGroupCallsPromise.set(true)
strongSelf.removeCurrentCallDisposable.set((call.canBeRemoved strongSelf.removeCurrentGroupCallDisposable.set((call.canBeRemoved
|> filter { $0 }
|> take(1)
|> deliverOnMainQueue).start(next: { [weak call] value in |> deliverOnMainQueue).start(next: { [weak call] value in
if value, let strongSelf = self, let call = call { guard let strongSelf = self, let call = call else {
return
}
if value {
if strongSelf.currentGroupCall === call { if strongSelf.currentGroupCall === call {
strongSelf.updateCurrentGroupCall(nil) strongSelf.updateCurrentGroupCall(nil)
strongSelf.currentGroupCallPromise.set(.single(nil)) strongSelf.currentGroupCallPromise.set(.single(nil))
strongSelf.hasActiveCallsPromise.set(false) strongSelf.hasActiveGroupCallsPromise.set(false)
} }
} }
})) }))

View File

@ -695,11 +695,13 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
})) }))
} else { } else {
self.leaveDisposable.set((leaveGroupCall(account: self.account, callId: callInfo.id, accessHash: callInfo.accessHash, source: localSsrc) self.leaveDisposable.set((leaveGroupCall(account: self.account, callId: callInfo.id, accessHash: callInfo.accessHash, source: localSsrc)
|> deliverOnMainQueue).start(completed: { [weak self] in |> deliverOnMainQueue).start(error: { [weak self] _ in
self?._canBeRemoved.set(.single(true))
}, completed: { [weak self] in
self?._canBeRemoved.set(.single(true)) self?._canBeRemoved.set(.single(true))
})) }))
} }
} else if case .requesting = self.internalState { } else {
self.callContext?.stop() self.callContext?.stop()
self.callContext = nil self.callContext = nil
self.requestDisposable.set(nil) self.requestDisposable.set(nil)