mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Screencast shutdown improvements
This commit is contained in:
parent
b7c9d2b233
commit
c20e99e4fc
@ -1470,6 +1470,7 @@ swift_library(
|
|||||||
"//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit",
|
"//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit",
|
||||||
"//submodules/BuildConfig:BuildConfig",
|
"//submodules/BuildConfig:BuildConfig",
|
||||||
"//submodules/WidgetItems:WidgetItems",
|
"//submodules/WidgetItems:WidgetItems",
|
||||||
|
"//submodules/BroadcastUploadHelpers:BroadcastUploadHelpers",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import CoreVideo
|
|||||||
import TelegramVoip
|
import TelegramVoip
|
||||||
import SwiftSignalKit
|
import SwiftSignalKit
|
||||||
import BuildConfig
|
import BuildConfig
|
||||||
|
import BroadcastUploadHelpers
|
||||||
|
|
||||||
private func rootPathForBasePath(_ appGroupPath: String) -> String {
|
private func rootPathForBasePath(_ appGroupPath: String) -> String {
|
||||||
return appGroupPath + "/telegram-data"
|
return appGroupPath + "/telegram-data"
|
||||||
@ -34,28 +35,29 @@ private func rootPathForBasePath(_ appGroupPath: String) -> String {
|
|||||||
super.beginRequest(with: context)
|
super.beginRequest(with: context)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func finishWithGenericError() {
|
private func finish(with reason: IpcGroupCallBufferBroadcastContext.Status.FinishReason) {
|
||||||
let error = NSError(domain: "BroadcastUploadExtension", code: 1, userInfo: [
|
var errorString: String?
|
||||||
NSLocalizedDescriptionKey: "Finished"
|
switch reason {
|
||||||
])
|
case .callEnded:
|
||||||
finishBroadcastWithError(error)
|
errorString = "You're not in a voice chat"
|
||||||
|
case .error:
|
||||||
/*self.callContext?.stop()
|
errorString = "Finished"
|
||||||
self.callContext = nil
|
case .screencastEnded:
|
||||||
|
break
|
||||||
self.ipcContext = nil*/
|
}
|
||||||
}
|
if let errorString = errorString {
|
||||||
|
let error = NSError(domain: "BroadcastUploadExtension", code: 1, userInfo: [
|
||||||
private func finishWithNoBroadcast() {
|
NSLocalizedDescriptionKey: errorString
|
||||||
let error = NSError(domain: "BroadcastUploadExtension", code: 1, userInfo: [
|
])
|
||||||
NSLocalizedDescriptionKey: "You're not in a voice chat"
|
finishBroadcastWithError(error)
|
||||||
])
|
} else {
|
||||||
finishBroadcastWithError(error)
|
finishBroadcastGracefully(self)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override public func broadcastStarted(withSetupInfo setupInfo: [String : NSObject]?) {
|
override public func broadcastStarted(withSetupInfo setupInfo: [String : NSObject]?) {
|
||||||
guard let appBundleIdentifier = Bundle.main.bundleIdentifier, let lastDotRange = appBundleIdentifier.range(of: ".", options: [.backwards]) else {
|
guard let appBundleIdentifier = Bundle.main.bundleIdentifier, let lastDotRange = appBundleIdentifier.range(of: ".", options: [.backwards]) else {
|
||||||
self.finishWithGenericError()
|
self.finish(with: .error)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,7 +67,7 @@ private func rootPathForBasePath(_ appGroupPath: String) -> String {
|
|||||||
let maybeAppGroupUrl = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appGroupName)
|
let maybeAppGroupUrl = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appGroupName)
|
||||||
|
|
||||||
guard let appGroupUrl = maybeAppGroupUrl else {
|
guard let appGroupUrl = maybeAppGroupUrl else {
|
||||||
self.finishWithGenericError()
|
self.finish(with: .error)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,8 +85,8 @@ private func rootPathForBasePath(_ appGroupPath: String) -> String {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
switch status {
|
switch status {
|
||||||
case .finished:
|
case let .finished(reason):
|
||||||
strongSelf.finishWithNoBroadcast()
|
strongSelf.finish(with: reason)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
22
submodules/BroadcastUploadHelpers/BUILD
Normal file
22
submodules/BroadcastUploadHelpers/BUILD
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
|
||||||
|
objc_library(
|
||||||
|
name = "BroadcastUploadHelpers",
|
||||||
|
enable_modules = True,
|
||||||
|
module_name = "BroadcastUploadHelpers",
|
||||||
|
srcs = glob([
|
||||||
|
"Sources/**/*.m",
|
||||||
|
"Sources/**/*.h",
|
||||||
|
]),
|
||||||
|
hdrs = glob([
|
||||||
|
"PublicHeaders/**/*.h",
|
||||||
|
]),
|
||||||
|
includes = [
|
||||||
|
"PublicHeaders",
|
||||||
|
],
|
||||||
|
sdk_frameworks = [
|
||||||
|
"Foundation",
|
||||||
|
],
|
||||||
|
visibility = [
|
||||||
|
"//visibility:public",
|
||||||
|
],
|
||||||
|
)
|
@ -0,0 +1,8 @@
|
|||||||
|
#ifndef BroadcastUploadHelpers_h
|
||||||
|
#define BroadcastUploadHelpers_h
|
||||||
|
|
||||||
|
#import <ReplayKit/ReplayKit.h>
|
||||||
|
|
||||||
|
void finishBroadcastGracefully(RPBroadcastSampleHandler * _Nonnull broadcastSampleHandler);
|
||||||
|
|
||||||
|
#endif /* BroadcastUploadHelpers_h */
|
8
submodules/BroadcastUploadHelpers/Sources/BroadcastUploadHelpers.m
Executable file
8
submodules/BroadcastUploadHelpers/Sources/BroadcastUploadHelpers.m
Executable file
@ -0,0 +1,8 @@
|
|||||||
|
#import <BroadcastUploadHelpers/BroadcastUploadHelpers.h>
|
||||||
|
|
||||||
|
void finishBroadcastGracefully(RPBroadcastSampleHandler * _Nonnull broadcastSampleHandler) {
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored "-Wnonnull"
|
||||||
|
[broadcastSampleHandler finishBroadcastWithError:nil];
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
}
|
@ -2637,6 +2637,8 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
|
|||||||
accessHash: callInfo.accessHash
|
accessHash: callInfo.accessHash
|
||||||
).start())
|
).start())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.screencastBufferServerContext?.stopScreencast()
|
||||||
}
|
}
|
||||||
/*if let _ = self.screencastIpcContext {
|
/*if let _ = self.screencastIpcContext {
|
||||||
self.screencastIpcContext = nil
|
self.screencastIpcContext = nil
|
||||||
|
@ -23,6 +23,11 @@ private struct KeepaliveInfo: Codable {
|
|||||||
var timestamp: Int32
|
var timestamp: Int32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private struct CutoffPayload: Codable {
|
||||||
|
var id: UInt32
|
||||||
|
var timestamp: Int32
|
||||||
|
}
|
||||||
|
|
||||||
private let checkInterval: Double = 0.2
|
private let checkInterval: Double = 0.2
|
||||||
private let keepaliveTimeout: Double = 2.0
|
private let keepaliveTimeout: Double = 2.0
|
||||||
|
|
||||||
@ -42,273 +47,14 @@ private func keepaliveInfoPath(basePath: String) -> String {
|
|||||||
return basePath + "/keepaliveInfo.json"
|
return basePath + "/keepaliveInfo.json"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func cutoffPayloadPath(basePath: String) -> String {
|
||||||
|
return basePath + "/cutoffPayload.json"
|
||||||
|
}
|
||||||
|
|
||||||
private func broadcastAppSocketPath(basePath: String) -> String {
|
private func broadcastAppSocketPath(basePath: String) -> String {
|
||||||
return basePath + "/0"
|
return basePath + "/0"
|
||||||
}
|
}
|
||||||
|
|
||||||
public final class IpcGroupCallAppContext {
|
|
||||||
private let basePath: String
|
|
||||||
private let currentId: UInt32
|
|
||||||
|
|
||||||
private let joinPayloadPromise = Promise<String>()
|
|
||||||
public var joinPayload: Signal<String, NoError> {
|
|
||||||
return self.joinPayloadPromise.get()
|
|
||||||
}
|
|
||||||
private var joinPayloadCheckTimer: SwiftSignalKit.Timer?
|
|
||||||
|
|
||||||
private let isActivePromise = ValuePromise<Bool>(false, ignoreRepeated: true)
|
|
||||||
public var isActive: Signal<Bool, NoError> {
|
|
||||||
return self.isActivePromise.get()
|
|
||||||
}
|
|
||||||
private var keepaliveCheckTimer: SwiftSignalKit.Timer?
|
|
||||||
|
|
||||||
public init(basePath: String) {
|
|
||||||
self.basePath = basePath
|
|
||||||
self.currentId = UInt32.random(in: 0 ..< UInt32.max)
|
|
||||||
|
|
||||||
let _ = try? FileManager.default.createDirectory(atPath: basePath, withIntermediateDirectories: true, attributes: nil)
|
|
||||||
|
|
||||||
self.sendRequest()
|
|
||||||
}
|
|
||||||
|
|
||||||
deinit {
|
|
||||||
self.joinPayloadCheckTimer?.invalidate()
|
|
||||||
self.keepaliveCheckTimer?.invalidate()
|
|
||||||
}
|
|
||||||
|
|
||||||
private func sendRequest() {
|
|
||||||
let timestamp = Int32(Date().timeIntervalSince1970)
|
|
||||||
let payloadDescription = PayloadDescription(
|
|
||||||
id: self.currentId,
|
|
||||||
timestamp: timestamp
|
|
||||||
)
|
|
||||||
guard let payloadDescriptionData = try? JSONEncoder().encode(payloadDescription) else {
|
|
||||||
preconditionFailure()
|
|
||||||
}
|
|
||||||
guard let _ = try? payloadDescriptionData.write(to: URL(fileURLWithPath: payloadDescriptionPath(basePath: self.basePath)), options: .atomic) else {
|
|
||||||
preconditionFailure()
|
|
||||||
}
|
|
||||||
|
|
||||||
self.receiveJoinPayload()
|
|
||||||
}
|
|
||||||
|
|
||||||
private func receiveJoinPayload() {
|
|
||||||
let joinPayloadCheckTimer = SwiftSignalKit.Timer(timeout: checkInterval, repeat: true, completion: { [weak self] in
|
|
||||||
self?.checkJoinPayload()
|
|
||||||
}, queue: .mainQueue())
|
|
||||||
self.joinPayloadCheckTimer = joinPayloadCheckTimer
|
|
||||||
joinPayloadCheckTimer.start()
|
|
||||||
}
|
|
||||||
|
|
||||||
private func checkJoinPayload() {
|
|
||||||
let filePath = joinPayloadPath(basePath: self.basePath)
|
|
||||||
guard let joinPayloadData = try? Data(contentsOf: URL(fileURLWithPath: filePath)) else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
self.joinPayloadCheckTimer?.invalidate()
|
|
||||||
let _ = try? FileManager.default.removeItem(atPath: filePath)
|
|
||||||
|
|
||||||
guard let joinPayload = try? JSONDecoder().decode(JoinPayload.self, from: joinPayloadData) else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if joinPayload.id != self.currentId {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
self.joinPayloadPromise.set(.single(joinPayload.string))
|
|
||||||
}
|
|
||||||
|
|
||||||
public func setJoinResponsePayload(_ joinResponsePayload: String) {
|
|
||||||
let inputJoinResponsePayload = JoinResponsePayload(
|
|
||||||
id: self.currentId,
|
|
||||||
string: joinResponsePayload
|
|
||||||
)
|
|
||||||
guard let inputJoinResponsePayloadData = try? JSONEncoder().encode(inputJoinResponsePayload) else {
|
|
||||||
preconditionFailure()
|
|
||||||
}
|
|
||||||
guard let _ = try? inputJoinResponsePayloadData.write(to: URL(fileURLWithPath: joinResponsePayloadPath(basePath: self.basePath)), options: .atomic) else {
|
|
||||||
preconditionFailure()
|
|
||||||
}
|
|
||||||
|
|
||||||
self.beginCheckingKeepaliveInfo()
|
|
||||||
}
|
|
||||||
|
|
||||||
private func beginCheckingKeepaliveInfo() {
|
|
||||||
let filePath = keepaliveInfoPath(basePath: self.basePath)
|
|
||||||
guard let keepaliveInfoData = try? Data(contentsOf: URL(fileURLWithPath: filePath)) else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
guard let keepaliveInfo = try? JSONDecoder().decode(KeepaliveInfo.self, from: keepaliveInfoData) else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if keepaliveInfo.id != self.currentId {
|
|
||||||
self.isActivePromise.set(false)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
let timestamp = Int32(Date().timeIntervalSince1970)
|
|
||||||
if keepaliveInfo.timestamp < timestamp - Int32(keepaliveTimeout) {
|
|
||||||
self.isActivePromise.set(false)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
self.isActivePromise.set(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public final class IpcGroupCallBroadcastContext {
|
|
||||||
public enum Request {
|
|
||||||
case request
|
|
||||||
case failed
|
|
||||||
}
|
|
||||||
|
|
||||||
private let basePath: String
|
|
||||||
|
|
||||||
private var currentId: UInt32?
|
|
||||||
|
|
||||||
private var requestCheckTimer: SwiftSignalKit.Timer?
|
|
||||||
private let requestPromise = Promise<Request>()
|
|
||||||
public var request: Signal<Request, NoError> {
|
|
||||||
return self.requestPromise.get()
|
|
||||||
}
|
|
||||||
|
|
||||||
private var joinResponsePayloadCheckTimer: SwiftSignalKit.Timer?
|
|
||||||
private let joinResponsePayloadPromise = Promise<String>()
|
|
||||||
public var joinResponsePayload: Signal<String, NoError> {
|
|
||||||
return self.joinResponsePayloadPromise.get()
|
|
||||||
}
|
|
||||||
|
|
||||||
private var keepaliveTimer: SwiftSignalKit.Timer?
|
|
||||||
|
|
||||||
public init(basePath: String) {
|
|
||||||
self.basePath = basePath
|
|
||||||
|
|
||||||
let _ = try? FileManager.default.createDirectory(atPath: basePath, withIntermediateDirectories: true, attributes: nil)
|
|
||||||
|
|
||||||
self.receiveRequest()
|
|
||||||
}
|
|
||||||
|
|
||||||
deinit {
|
|
||||||
self.requestCheckTimer?.invalidate()
|
|
||||||
self.joinResponsePayloadCheckTimer?.invalidate()
|
|
||||||
self.keepaliveTimer?.invalidate()
|
|
||||||
self.endActiveIndication()
|
|
||||||
}
|
|
||||||
|
|
||||||
private func receiveRequest() {
|
|
||||||
let requestCheckTimer = SwiftSignalKit.Timer(timeout: checkInterval, repeat: true, completion: { [weak self] in
|
|
||||||
self?.checkRequest()
|
|
||||||
}, queue: .mainQueue())
|
|
||||||
self.requestCheckTimer = requestCheckTimer
|
|
||||||
requestCheckTimer.start()
|
|
||||||
}
|
|
||||||
|
|
||||||
private func checkRequest() {
|
|
||||||
let filePath = payloadDescriptionPath(basePath: self.basePath)
|
|
||||||
guard let payloadDescriptionData = try? Data(contentsOf: URL(fileURLWithPath: filePath)) else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let _ = try? FileManager.default.removeItem(atPath: filePath)
|
|
||||||
|
|
||||||
guard let payloadDescription = try? JSONDecoder().decode(PayloadDescription.self, from: payloadDescriptionData) else {
|
|
||||||
self.requestCheckTimer?.invalidate()
|
|
||||||
self.requestPromise.set(.single(.failed))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
let timestamp = Int32(Date().timeIntervalSince1970)
|
|
||||||
if payloadDescription.timestamp < timestamp - 1 * 60 {
|
|
||||||
self.requestPromise.set(.single(.failed))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
self.requestCheckTimer?.invalidate()
|
|
||||||
|
|
||||||
self.currentId = payloadDescription.id
|
|
||||||
self.requestPromise.set(.single(.request))
|
|
||||||
}
|
|
||||||
|
|
||||||
public func setJoinPayload(_ joinPayload: String) {
|
|
||||||
guard let currentId = self.currentId else {
|
|
||||||
preconditionFailure()
|
|
||||||
}
|
|
||||||
let inputPayload = JoinPayload(
|
|
||||||
id: currentId,
|
|
||||||
string: joinPayload
|
|
||||||
)
|
|
||||||
guard let inputPayloadData = try? JSONEncoder().encode(inputPayload) else {
|
|
||||||
preconditionFailure()
|
|
||||||
}
|
|
||||||
guard let _ = try? inputPayloadData.write(to: URL(fileURLWithPath: joinPayloadPath(basePath: self.basePath)), options: .atomic) else {
|
|
||||||
preconditionFailure()
|
|
||||||
}
|
|
||||||
|
|
||||||
self.receiveJoinResponsePayload()
|
|
||||||
}
|
|
||||||
|
|
||||||
private func receiveJoinResponsePayload() {
|
|
||||||
let joinResponsePayloadCheckTimer = SwiftSignalKit.Timer(timeout: checkInterval, repeat: true, completion: { [weak self] in
|
|
||||||
self?.checkJoinResponsePayload()
|
|
||||||
}, queue: .mainQueue())
|
|
||||||
self.joinResponsePayloadCheckTimer = joinResponsePayloadCheckTimer
|
|
||||||
joinResponsePayloadCheckTimer.start()
|
|
||||||
}
|
|
||||||
|
|
||||||
private func checkJoinResponsePayload() {
|
|
||||||
let filePath = joinResponsePayloadPath(basePath: self.basePath)
|
|
||||||
guard let joinResponsePayloadData = try? Data(contentsOf: URL(fileURLWithPath: filePath)) else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
self.joinResponsePayloadCheckTimer?.invalidate()
|
|
||||||
let _ = try? FileManager.default.removeItem(atPath: filePath)
|
|
||||||
|
|
||||||
guard let joinResponsePayload = try? JSONDecoder().decode(JoinResponsePayload.self, from: joinResponsePayloadData) else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if joinResponsePayload.id != self.currentId {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
self.joinResponsePayloadPromise.set(.single(joinResponsePayload.string))
|
|
||||||
}
|
|
||||||
|
|
||||||
public func beginActiveIndication() {
|
|
||||||
if self.keepaliveTimer != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
self.writeKeepaliveInfo()
|
|
||||||
|
|
||||||
let keepaliveTimer = SwiftSignalKit.Timer(timeout: 1.0, repeat: true, completion: { [weak self] in
|
|
||||||
self?.writeKeepaliveInfo()
|
|
||||||
}, queue: .mainQueue())
|
|
||||||
self.keepaliveTimer = keepaliveTimer
|
|
||||||
keepaliveTimer.start()
|
|
||||||
}
|
|
||||||
|
|
||||||
private func writeKeepaliveInfo() {
|
|
||||||
guard let currentId = self.currentId else {
|
|
||||||
preconditionFailure()
|
|
||||||
}
|
|
||||||
let keepaliveInfo = KeepaliveInfo(
|
|
||||||
id: currentId,
|
|
||||||
timestamp: Int32(Date().timeIntervalSince1970)
|
|
||||||
)
|
|
||||||
guard let keepaliveInfoData = try? JSONEncoder().encode(keepaliveInfo) else {
|
|
||||||
preconditionFailure()
|
|
||||||
}
|
|
||||||
guard let _ = try? keepaliveInfoData.write(to: URL(fileURLWithPath: keepaliveInfoPath(basePath: self.basePath)), options: .atomic) else {
|
|
||||||
preconditionFailure()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func endActiveIndication() {
|
|
||||||
let _ = try? FileManager.default.removeItem(atPath: keepaliveInfoPath(basePath: self.basePath))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private final class FdReadConnection {
|
private final class FdReadConnection {
|
||||||
private final class PendingData {
|
private final class PendingData {
|
||||||
var data: Data
|
var data: Data
|
||||||
@ -732,11 +478,30 @@ public final class IpcGroupCallBufferAppContext {
|
|||||||
|
|
||||||
self.isActivePromise.set(true)
|
self.isActivePromise.set(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func stopScreencast() {
|
||||||
|
let timestamp = Int32(Date().timeIntervalSince1970)
|
||||||
|
let cutoffPayload = CutoffPayload(
|
||||||
|
id: self.id,
|
||||||
|
timestamp: timestamp
|
||||||
|
)
|
||||||
|
guard let cutoffPayloadData = try? JSONEncoder().encode(cutoffPayload) else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
guard let _ = try? cutoffPayloadData.write(to: URL(fileURLWithPath: cutoffPayloadPath(basePath: self.basePath)), options: .atomic) else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public final class IpcGroupCallBufferBroadcastContext {
|
public final class IpcGroupCallBufferBroadcastContext {
|
||||||
public enum Status {
|
public enum Status {
|
||||||
case finished
|
public enum FinishReason {
|
||||||
|
case screencastEnded
|
||||||
|
case callEnded
|
||||||
|
case error
|
||||||
|
}
|
||||||
|
case finished(FinishReason)
|
||||||
}
|
}
|
||||||
|
|
||||||
private let basePath: String
|
private let basePath: String
|
||||||
@ -752,8 +517,8 @@ public final class IpcGroupCallBufferBroadcastContext {
|
|||||||
private var currentId: UInt32?
|
private var currentId: UInt32?
|
||||||
|
|
||||||
private var callActiveInfoTimer: SwiftSignalKit.Timer?
|
private var callActiveInfoTimer: SwiftSignalKit.Timer?
|
||||||
|
|
||||||
private var keepaliveInfoTimer: SwiftSignalKit.Timer?
|
private var keepaliveInfoTimer: SwiftSignalKit.Timer?
|
||||||
|
private var screencastCutoffTimer: SwiftSignalKit.Timer?
|
||||||
|
|
||||||
public init(basePath: String) {
|
public init(basePath: String) {
|
||||||
self.basePath = basePath
|
self.basePath = basePath
|
||||||
@ -766,6 +531,12 @@ public final class IpcGroupCallBufferBroadcastContext {
|
|||||||
}, queue: .mainQueue())
|
}, queue: .mainQueue())
|
||||||
self.callActiveInfoTimer = callActiveInfoTimer
|
self.callActiveInfoTimer = callActiveInfoTimer
|
||||||
callActiveInfoTimer.start()
|
callActiveInfoTimer.start()
|
||||||
|
|
||||||
|
let screencastCutoffTimer = SwiftSignalKit.Timer(timeout: 1.0, repeat: true, completion: { [weak self] in
|
||||||
|
self?.updateScreencastCutoff()
|
||||||
|
}, queue: .mainQueue())
|
||||||
|
self.screencastCutoffTimer = screencastCutoffTimer
|
||||||
|
screencastCutoffTimer.start()
|
||||||
}
|
}
|
||||||
|
|
||||||
deinit {
|
deinit {
|
||||||
@ -773,28 +544,45 @@ public final class IpcGroupCallBufferBroadcastContext {
|
|||||||
|
|
||||||
self.callActiveInfoTimer?.invalidate()
|
self.callActiveInfoTimer?.invalidate()
|
||||||
self.keepaliveInfoTimer?.invalidate()
|
self.keepaliveInfoTimer?.invalidate()
|
||||||
|
self.screencastCutoffTimer?.invalidate()
|
||||||
|
}
|
||||||
|
|
||||||
|
private func updateScreencastCutoff() {
|
||||||
|
let filePath = cutoffPayloadPath(basePath: self.basePath)
|
||||||
|
guard let cutoffPayloadData = try? Data(contentsOf: URL(fileURLWithPath: filePath)) else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let cutoffPayload = try? JSONDecoder().decode(CutoffPayload.self, from: cutoffPayloadData) else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if let currentId = self.currentId, currentId == cutoffPayload.id {
|
||||||
|
self.statusPromise.set(.single(.finished(.screencastEnded)))
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func updateCallIsActive() {
|
private func updateCallIsActive() {
|
||||||
let filePath = payloadDescriptionPath(basePath: self.basePath)
|
let filePath = payloadDescriptionPath(basePath: self.basePath)
|
||||||
guard let payloadDescriptionData = try? Data(contentsOf: URL(fileURLWithPath: filePath)) else {
|
guard let payloadDescriptionData = try? Data(contentsOf: URL(fileURLWithPath: filePath)) else {
|
||||||
self.statusPromise.set(.single(.finished))
|
self.statusPromise.set(.single(.finished(.error)))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
guard let payloadDescription = try? JSONDecoder().decode(PayloadDescription.self, from: payloadDescriptionData) else {
|
guard let payloadDescription = try? JSONDecoder().decode(PayloadDescription.self, from: payloadDescriptionData) else {
|
||||||
self.statusPromise.set(.single(.finished))
|
self.statusPromise.set(.single(.finished(.error)))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let timestamp = Int32(Date().timeIntervalSince1970)
|
let timestamp = Int32(Date().timeIntervalSince1970)
|
||||||
if payloadDescription.timestamp < timestamp - 4 {
|
if payloadDescription.timestamp < timestamp - 4 {
|
||||||
self.statusPromise.set(.single(.finished))
|
self.statusPromise.set(.single(.finished(.callEnded)))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if let currentId = self.currentId {
|
if let currentId = self.currentId {
|
||||||
if currentId != payloadDescription.id {
|
if currentId != payloadDescription.id {
|
||||||
self.statusPromise.set(.single(.finished))
|
self.statusPromise.set(.single(.finished(.callEnded)))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.currentId = payloadDescription.id
|
self.currentId = payloadDescription.id
|
||||||
|
Loading…
x
Reference in New Issue
Block a user