Support tgvoip derived state

This commit is contained in:
Peter 2018-12-19 22:44:00 +03:00
parent 3841061c98
commit 78007cedfd
9 changed files with 84 additions and 11 deletions

View File

@ -101,6 +101,7 @@
09FE756D2153F5F900A3120F /* CallRouteActionSheetItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09FE756C2153F5F900A3120F /* CallRouteActionSheetItem.swift */; };
9F06830921A404AB001D8EDB /* NotificationExceptionControllerNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F06830821A404AB001D8EDB /* NotificationExceptionControllerNode.swift */; };
9F06830B21A404C4001D8EDB /* NotificationExcetionSettingsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F06830A21A404C4001D8EDB /* NotificationExcetionSettingsController.swift */; };
D005808B21CAB8F000CB7CD3 /* VoipDerivedState.swift in Sources */ = {isa = PBXBuildFile; fileRef = D005808A21CAB8F000CB7CD3 /* VoipDerivedState.swift */; };
D0068FA821760FA300D1B315 /* StoreDownloadedMedia.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0068FA721760FA300D1B315 /* StoreDownloadedMedia.swift */; };
D007019C2029E8F2006B9E34 /* LegqacyICloudFileController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D007019B2029E8F2006B9E34 /* LegqacyICloudFileController.swift */; };
D007019E2029EFDD006B9E34 /* ICloudResources.swift in Sources */ = {isa = PBXBuildFile; fileRef = D007019D2029EFDD006B9E34 /* ICloudResources.swift */; };
@ -1210,6 +1211,7 @@
D003702D1DA43052004308D3 /* ItemListAvatarAndNameItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemListAvatarAndNameItem.swift; sourceTree = "<group>"; };
D003702F1DA43077004308D3 /* ItemListItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemListItem.swift; sourceTree = "<group>"; };
D00370311DA46C06004308D3 /* ItemListTextWithLabelItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemListTextWithLabelItem.swift; sourceTree = "<group>"; };
D005808A21CAB8F000CB7CD3 /* VoipDerivedState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VoipDerivedState.swift; sourceTree = "<group>"; };
D0068FA721760FA300D1B315 /* StoreDownloadedMedia.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StoreDownloadedMedia.swift; sourceTree = "<group>"; };
D007019B2029E8F2006B9E34 /* LegqacyICloudFileController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LegqacyICloudFileController.swift; sourceTree = "<group>"; };
D007019D2029EFDD006B9E34 /* ICloudResources.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ICloudResources.swift; sourceTree = "<group>"; };
@ -3304,6 +3306,7 @@
D08A10BA211DF7A80077488B /* StickerSettings.swift */,
0952D1762177FB5400194860 /* WatchPresetSettings.swift */,
0962E67C21BA048D00245FD9 /* WebSearchSettings.swift */,
D005808A21CAB8F000CB7CD3 /* VoipDerivedState.swift */,
);
name = Settings;
sourceTree = "<group>";
@ -5916,6 +5919,7 @@
D0EC6E7B1EB9F58900EBF1C3 /* DebugAccountsController.swift in Sources */,
D093D8262069A31700BC3599 /* FormControllerItem.swift in Sources */,
D0EC6E7C1EB9F58900EBF1C3 /* UsernameSetupController.swift in Sources */,
D005808B21CAB8F000CB7CD3 /* VoipDerivedState.swift in Sources */,
D0471B621EFEB5B70074D609 /* BotPaymentSwitchItemNode.swift in Sources */,
D09250041FE5363D003F693F /* ExperimentalSettings.swift in Sources */,
D0E8175B201254FA00B82BBB /* ChatRecentActionsEmptyNode.swift in Sources */,

View File

@ -31,6 +31,7 @@ private var telegramUIDeclaredEncodables: Void = {
declareEncodable(WatchPresetSettings.self, f: { WatchPresetSettings(decoder: $0) })
declareEncodable(WebSearchSettings.self, f: { WebSearchSettings(decoder: $0) })
declareEncodable(RecentWebSearchQueryItem.self, f: { RecentWebSearchQueryItem(decoder: $0) })
declareEncodable(VoipDerivedState.self, f: { VoipDerivedState(decoder: $0) })
return
}()

View File

@ -115,6 +115,7 @@ final class OngoingCallContext {
let internalId: CallSessionInternalId
private let queue = Queue()
private let postbox: Postbox
private let callSessionManager: CallSessionManager
private var contextRef: Unmanaged<OngoingCallThreadLocalContext>?
@ -148,11 +149,12 @@ final class OngoingCallContext {
return OngoingCallThreadLocalContext.maxLayer()
}
init(account: Account, callSessionManager: CallSessionManager, internalId: CallSessionInternalId, proxyServer: ProxyServerSettings?, initialNetworkType: NetworkType, updatedNetworkType: Signal<NetworkType, NoError>, serializedData: String?, dataSaving: VoiceCallDataSaving, logPath: String) {
init(account: Account, callSessionManager: CallSessionManager, internalId: CallSessionInternalId, proxyServer: ProxyServerSettings?, initialNetworkType: NetworkType, updatedNetworkType: Signal<NetworkType, NoError>, serializedData: String?, dataSaving: VoiceCallDataSaving, derivedState: VoipDerivedState, logPath: String) {
let _ = setupLogs
OngoingCallThreadLocalContext.applyServerConfig(serializedData)
self.internalId = internalId
self.postbox = account.postbox
self.callSessionManager = callSessionManager
let queue = self.queue
@ -166,7 +168,7 @@ final class OngoingCallContext {
break
}
}
let context = OngoingCallThreadLocalContext(queue: OngoingCallThreadLocalContextQueueImpl(queue: queue), proxy: voipProxyServer, networkType: ongoingNetworkTypeForType(initialNetworkType), dataSaving: ongoingDataSavingForType(dataSaving), logPath: logPath)
let context = OngoingCallThreadLocalContext(queue: OngoingCallThreadLocalContextQueueImpl(queue: queue), proxy: voipProxyServer, networkType: ongoingNetworkTypeForType(initialNetworkType), dataSaving: ongoingDataSavingForType(dataSaving), logPath: logPath, derivedState: derivedState.data)
self.contextRef = Unmanaged.passRetained(context)
context.stateChanged = { [weak self] state in
self?.contextState.set(.single(state))
@ -228,6 +230,10 @@ final class OngoingCallContext {
func stop() {
self.withContext { context in
context.stop()
let derivedState = context.getDerivedState()
let _ = updateVoipDerivedStateInteractively(postbox: self.postbox, { _ in
return VoipDerivedState(data: derivedState)
}).start()
}
}

View File

@ -63,12 +63,13 @@ typedef NS_ENUM(int32_t, OngoingCallDataSaving) {
@property (nonatomic, copy) void (^ _Nullable signalBarsChanged)(int32_t);
@property (nonatomic, copy) void (^ _Nullable callEnded)(NSString * _Nullable debugLog, int64_t bytesSentWifi, int64_t bytesReceivedWifi, int64_t bytesSentMobile, int64_t bytesReceivedMobile);
- (instancetype _Nonnull)initWithQueue:(id<OngoingCallThreadLocalContextQueue> _Nonnull)queue proxy:(VoipProxyServer * _Nullable)proxy networkType:(OngoingCallNetworkType)networkType dataSaving:(OngoingCallDataSaving)dataSaving logPath:(NSString * _Nonnull)logPath;
- (instancetype _Nonnull)initWithQueue:(id<OngoingCallThreadLocalContextQueue> _Nonnull)queue proxy:(VoipProxyServer * _Nullable)proxy networkType:(OngoingCallNetworkType)networkType dataSaving:(OngoingCallDataSaving)dataSaving logPath:(NSString * _Nonnull)logPath derivedState:(NSData * _Nonnull)derivedState;
- (void)startWithKey:(NSData * _Nonnull)key isOutgoing:(bool)isOutgoing primaryConnection:(OngoingCallConnectionDescription * _Nonnull)primaryConnection alternativeConnections:(NSArray<OngoingCallConnectionDescription *> * _Nonnull)alternativeConnections maxLayer:(int32_t)maxLayer allowP2P:(BOOL)allowP2P;
- (void)stop;
- (NSString * _Nullable)debugInfo;
- (NSString * _Nullable)version;
- (NSData * _Nonnull)getDerivedState;
- (void)setIsMuted:(bool)isMuted;
- (void)setNetworkType:(OngoingCallNetworkType)networkType;

View File

@ -214,7 +214,7 @@ static int callControllerDataSavingForType(OngoingCallDataSaving type) {
return tgvoip::VoIPController::GetConnectionMaxLayer();
}
- (instancetype _Nonnull)initWithQueue:(id<OngoingCallThreadLocalContextQueue> _Nonnull)queue proxy:(VoipProxyServer * _Nullable)proxy networkType:(OngoingCallNetworkType)networkType dataSaving:(OngoingCallDataSaving)dataSaving logPath:(NSString * _Nonnull)logPath {
- (instancetype _Nonnull)initWithQueue:(id<OngoingCallThreadLocalContextQueue> _Nonnull)queue proxy:(VoipProxyServer * _Nullable)proxy networkType:(OngoingCallNetworkType)networkType dataSaving:(OngoingCallDataSaving)dataSaving logPath:(NSString * _Nonnull)logPath derivedState:(NSData * _Nonnull)derivedState {
self = [super init];
if (self != nil) {
_queue = queue;
@ -231,6 +231,10 @@ static int callControllerDataSavingForType(OngoingCallDataSaving type) {
_controller = new tgvoip::VoIPController();
_controller->implData = (void *)((intptr_t)_contextId);
std::vector<uint8_t> derivedStateValue;
derivedStateValue.resize(derivedState.length);
[derivedState getBytes:derivedStateValue.data() length:derivedState.length];
_controller->SetPersistentState(derivedStateValue);
if (proxy != nil) {
_controller->SetProxy(tgvoip::PROXY_SOCKS5, proxy.host.UTF8String, (uint16_t)proxy.port, proxy.username.UTF8String ?: "", proxy.password.UTF8String ?: "");
@ -337,6 +341,15 @@ static int callControllerDataSavingForType(OngoingCallDataSaving type) {
}
}
- (NSData * _Nonnull)getDerivedState {
if (_controller != nil) {
std::vector<uint8_t> derivedStateValue = _controller->GetPersistentState();
return [[NSData alloc] initWithBytes:derivedStateValue.data() length:derivedStateValue.size()];
} else {
return [NSData data];
}
}
- (void)controllerStateChanged:(int)state {
OngoingCallState callState = OngoingCallStateInitializing;
switch (state) {

View File

@ -19,6 +19,7 @@ private enum ApplicationSpecificPreferencesKeyValues: Int32 {
case stickerSettings = 13
case watchPresetSettings = 14
case webSearchSettings = 15
case voipDerivedState = 16
}
public struct ApplicationSpecificPreferencesKeys {
@ -38,6 +39,7 @@ public struct ApplicationSpecificPreferencesKeys {
public static let stickerSettings = applicationSpecificPreferencesKey(ApplicationSpecificPreferencesKeyValues.stickerSettings.rawValue)
public static let watchPresetSettings = applicationSpecificPreferencesKey(ApplicationSpecificPreferencesKeyValues.watchPresetSettings.rawValue)
public static let webSearchSettings = applicationSpecificPreferencesKey(ApplicationSpecificPreferencesKeyValues.webSearchSettings.rawValue)
public static let voipDerivedState = applicationSpecificPreferencesKey(ApplicationSpecificPreferencesKeyValues.voipDerivedState.rawValue)
}
private enum ApplicationSpecificItemCacheCollectionIdValues: Int8 {

View File

@ -220,7 +220,7 @@ public final class PresentationCall {
private var droppedCall = false
private var dropCallKitCallTimer: SwiftSignalKit.Timer?
init(account: Account, audioSession: ManagedAudioSession, callSessionManager: CallSessionManager, callKitIntegration: CallKitIntegration?, serializedData: String?, dataSaving: VoiceCallDataSaving, getDeviceAccessData: @escaping () -> (presentationData: PresentationData, present: (ViewController, Any?) -> Void, openSettings: () -> Void), internalId: CallSessionInternalId, peerId: PeerId, isOutgoing: Bool, peer: Peer?, proxyServer: ProxyServerSettings?, currentNetworkType: NetworkType, updatedNetworkType: Signal<NetworkType, NoError>) {
init(account: Account, audioSession: ManagedAudioSession, callSessionManager: CallSessionManager, callKitIntegration: CallKitIntegration?, serializedData: String?, dataSaving: VoiceCallDataSaving, derivedState: VoipDerivedState, getDeviceAccessData: @escaping () -> (presentationData: PresentationData, present: (ViewController, Any?) -> Void, openSettings: () -> Void), internalId: CallSessionInternalId, peerId: PeerId, isOutgoing: Bool, peer: Peer?, proxyServer: ProxyServerSettings?, currentNetworkType: NetworkType, updatedNetworkType: Signal<NetworkType, NoError>) {
self.account = account
self.audioSession = audioSession
self.callSessionManager = callSessionManager
@ -232,7 +232,7 @@ public final class PresentationCall {
self.isOutgoing = isOutgoing
self.peer = peer
self.ongoingContext = OngoingCallContext(account: account, callSessionManager: self.callSessionManager, internalId: self.internalId, proxyServer: proxyServer, initialNetworkType: currentNetworkType, updatedNetworkType: updatedNetworkType, serializedData: serializedData, dataSaving: dataSaving, logPath: "")
self.ongoingContext = OngoingCallContext(account: account, callSessionManager: self.callSessionManager, internalId: self.internalId, proxyServer: proxyServer, initialNetworkType: currentNetworkType, updatedNetworkType: updatedNetworkType, serializedData: serializedData, dataSaving: dataSaving, derivedState: derivedState, logPath: "")
var didReceiveAudioOutputs = false
self.sessionStateDisposable = (callSessionManager.callState(internalId: internalId)

View File

@ -59,7 +59,7 @@ public final class PresentationCallManager {
private var proxyServer: ProxyServerSettings?
private var proxyServerDisposable: Disposable?
private var callSettings: (VoiceCallSettings, VoipConfiguration)?
private var callSettings: (VoiceCallSettings, VoipConfiguration, VoipDerivedState)?
private var callSettingsDisposable: Disposable?
public static var voipMaxLayer: Int32 {
@ -192,12 +192,13 @@ public final class PresentationCallManager {
}
})
self.callSettingsDisposable = (postbox.preferencesView(keys: [ApplicationSpecificPreferencesKeys.voiceCallSettings, PreferencesKeys.voipConfiguration])
self.callSettingsDisposable = (postbox.preferencesView(keys: [ApplicationSpecificPreferencesKeys.voiceCallSettings, PreferencesKeys.voipConfiguration, ApplicationSpecificPreferencesKeys.voipDerivedState])
|> deliverOnMainQueue).start(next: { [weak self] preferences in
let callSettings = preferences.values[ApplicationSpecificPreferencesKeys.voiceCallSettings] as? VoiceCallSettings ?? .defaultSettings
let configuration = preferences.values[PreferencesKeys.voipConfiguration] as? VoipConfiguration ?? .defaultValue
let derivedState = preferences.values[ApplicationSpecificPreferencesKeys.voipDerivedState] as? VoipDerivedState ?? .default
if let strongSelf = self {
strongSelf.callSettings = (callSettings, configuration)
strongSelf.callSettings = (callSettings, configuration, derivedState)
if let legacyP2PMode = callSettings.legacyP2PMode {
_ = updateVoiceCallSettingsSettingsInteractively(postbox: postbox, { settings -> VoiceCallSettings in
@ -232,7 +233,7 @@ public final class PresentationCallManager {
private func ringingStatesUpdated(_ ringingStates: [(Peer, CallSessionRingingState, Bool)], currentNetworkType: NetworkType, enableCallKit: Bool) {
if let firstState = ringingStates.first {
if self.currentCall == nil {
let call = PresentationCall(account: self.account, audioSession: self.audioSession, callSessionManager: self.callSessionManager, callKitIntegration: enableCallKit ? callKitIntegrationIfEnabled(self.callKitIntegration, settings: self.callSettings?.0) : nil, serializedData: self.callSettings?.1.serializedData, dataSaving: self.callSettings?.0.dataSaving ?? .never, getDeviceAccessData: self.getDeviceAccessData, internalId: firstState.1.id, peerId: firstState.1.peerId, isOutgoing: false, peer: firstState.0, proxyServer: self.proxyServer, currentNetworkType: currentNetworkType, updatedNetworkType: self.networkType)
let call = PresentationCall(account: self.account, audioSession: self.audioSession, callSessionManager: self.callSessionManager, callKitIntegration: enableCallKit ? callKitIntegrationIfEnabled(self.callKitIntegration, settings: self.callSettings?.0) : nil, serializedData: self.callSettings?.1.serializedData, dataSaving: self.callSettings?.0.dataSaving ?? .never, derivedState: self.callSettings?.2 ?? VoipDerivedState.default, getDeviceAccessData: self.getDeviceAccessData, internalId: firstState.1.id, peerId: firstState.1.peerId, isOutgoing: false, peer: firstState.0, proxyServer: self.proxyServer, currentNetworkType: currentNetworkType, updatedNetworkType: self.networkType)
self.currentCall = call
self.currentCallPromise.set(.single(call))
self.hasActiveCallsPromise.set(true)
@ -358,7 +359,7 @@ public final class PresentationCallManager {
currentCall.rejectBusy()
}
let call = PresentationCall(account: strongSelf.account, audioSession: strongSelf.audioSession, callSessionManager: strongSelf.callSessionManager, callKitIntegration: callKitIntegrationIfEnabled(strongSelf.callKitIntegration, settings: strongSelf.callSettings?.0), serializedData: strongSelf.callSettings?.1.serializedData, dataSaving: strongSelf.callSettings?.0.dataSaving ?? .never, getDeviceAccessData: strongSelf.getDeviceAccessData, internalId: internalId, peerId: peerId, isOutgoing: true, peer: nil, proxyServer: strongSelf.proxyServer, currentNetworkType: currentNetworkType, updatedNetworkType: strongSelf.networkType)
let call = PresentationCall(account: strongSelf.account, audioSession: strongSelf.audioSession, callSessionManager: strongSelf.callSessionManager, callKitIntegration: callKitIntegrationIfEnabled(strongSelf.callKitIntegration, settings: strongSelf.callSettings?.0), serializedData: strongSelf.callSettings?.1.serializedData, dataSaving: strongSelf.callSettings?.0.dataSaving ?? .never, detivedState: strongSelf.callSettings?.2 ?? VoipDerivedState.default, getDeviceAccessData: strongSelf.getDeviceAccessData, internalId: internalId, peerId: peerId, isOutgoing: true, peer: nil, proxyServer: strongSelf.proxyServer, currentNetworkType: currentNetworkType, updatedNetworkType: strongSelf.networkType)
strongSelf.currentCall = call
strongSelf.currentCallPromise.set(.single(call))
strongSelf.hasActiveCallsPromise.set(true)

View File

@ -0,0 +1,45 @@
import Foundation
import Postbox
import SwiftSignalKit
struct VoipDerivedState: Equatable, PreferencesEntry {
var data: Data
static var `default`: VoipDerivedState {
return VoipDerivedState(data: Data())
}
init(data: Data) {
self.data = data
}
init(decoder: PostboxDecoder) {
self.data = decoder.decodeDataForKey("data") ?? Data()
}
func encode(_ encoder: PostboxEncoder) {
encoder.encodeData(self.data, forKey: "data")
}
func isEqual(to: PreferencesEntry) -> Bool {
if let to = to as? VoipDerivedState {
return self == to
} else {
return false
}
}
}
func updateVoipDerivedStateInteractively(postbox: Postbox, _ f: @escaping (VoipDerivedState) -> VoipDerivedState) -> Signal<Void, NoError> {
return postbox.transaction { transaction -> Void in
transaction.updatePreferencesEntry(key: ApplicationSpecificPreferencesKeys.voipDerivedState, { entry in
let currentSettings: VoipDerivedState
if let entry = entry as? VoipDerivedState {
currentSettings = entry
} else {
currentSettings = .default
}
return f(currentSettings)
})
}
}