зеркало из https://github.com/nextcloud/talk-ios.git
Ensure signaling settings availability
Signed-off-by: Marcel Müller <marcel-mueller@gmx.de>
This commit is contained in:
Родитель
e775bde2f9
Коммит
337b9576f4
|
@ -97,6 +97,9 @@ static NSString * const kNCScreenTrackKind = @"screen";
|
|||
_signalingController.observer = self;
|
||||
|
||||
_account = [[NCDatabaseManager sharedInstance] activeAccount];
|
||||
|
||||
// NCCallController is only initialized after joining the room. At that point we ensured that there's
|
||||
// an external signaling controller set, in case we are using external signaling.
|
||||
_externalSignalingController = [[NCSettingsController sharedInstance] externalSignalingControllerForAccountId:_account.accountId];
|
||||
_externalSignalingController.delegate = self;
|
||||
|
||||
|
|
|
@ -111,14 +111,12 @@ NSString * const NCConnectionStateHasChangedNotification = @"NCConnectionStat
|
|||
}
|
||||
|
||||
[self setAppState:kAppStateMissingSignalingConfiguration];
|
||||
[[NCSettingsController sharedInstance] getSignalingConfigurationForAccountId:activeAccount.accountId withCompletionBlock:^(NSError *error) {
|
||||
[[NCSettingsController sharedInstance] updateSignalingConfigurationForAccountId:activeAccount.accountId withCompletionBlock:^(NCExternalSignalingController * _Nullable signalingServer, NSError *error) {
|
||||
if (error) {
|
||||
[self notifyAppState];
|
||||
return;
|
||||
}
|
||||
|
||||
// SetSignalingConfiguration should be called just once
|
||||
[[NCSettingsController sharedInstance] setSignalingConfigurationForAccountId:activeAccount.accountId];
|
||||
[self checkAppState];
|
||||
}];
|
||||
}];
|
||||
|
|
|
@ -370,7 +370,7 @@ NSString * const NCExternalSignalingControllerDidReceiveStoppedTypingNotificatio
|
|||
sessionChanged = NO;
|
||||
[self.delegate externalSignalingControllerWillRejoinCall:self];
|
||||
|
||||
[[NCRoomsManager sharedInstance] rejoinRoom:_currentRoom completionBlock:^(NSString * _Nullable sessionId, NCRoom * _Nullable room, NSError * _Nullable error, NSInteger statusCode, NSString * _Nullable statusReason) {
|
||||
[[NCRoomsManager sharedInstance] rejoinRoomForCall:_currentRoom completionBlock:^(NSString * _Nullable sessionId, NCRoom * _Nullable room, NSError * _Nullable error, NSInteger statusCode, NSString * _Nullable statusReason) {
|
||||
[self.delegate externalSignalingControllerShouldRejoinCall:self];
|
||||
}];
|
||||
}
|
||||
|
|
|
@ -7,12 +7,15 @@ import Foundation
|
|||
|
||||
@objc extension NCRoomsManager {
|
||||
|
||||
public static let statusCodeFailedToJoinExternal = 997
|
||||
public static let statusCodeShouldIgnoreAttemptButJoinedSuccessfully = 998
|
||||
public static let statusCodeIgnoreJoinAttempt = 999
|
||||
|
||||
// MARK: - Join/Leave room
|
||||
|
||||
public func joinRoom(_ token: String, forCall call: Bool) {
|
||||
NCUtils.log("Joining room \(token) for call \(call)")
|
||||
|
||||
// Clean up joining room flag and attempts
|
||||
self.joiningRoomToken = nil
|
||||
self.joiningSessionId = nil
|
||||
|
@ -33,6 +36,8 @@ import Foundation
|
|||
userInfo["token"] = token
|
||||
|
||||
if let roomController = self.activeRooms[token] as? NCRoomController {
|
||||
NCUtils.log("JoinRoomHelper: Found active room controller")
|
||||
|
||||
if call {
|
||||
roomController.inCall = true
|
||||
} else {
|
||||
|
@ -103,6 +108,8 @@ import Foundation
|
|||
NCUtils.log("Could not join room. Status code: \(statusCode). Error: \(error?.localizedDescription ?? "")")
|
||||
}
|
||||
|
||||
self.joiningRoomToken = nil
|
||||
self.joiningSessionId = nil
|
||||
NotificationCenter.default.post(name: .NCRoomsManagerDidJoinRoom, object: self, userInfo: userInfo)
|
||||
}
|
||||
}
|
||||
|
@ -150,19 +157,24 @@ import Foundation
|
|||
|
||||
NCUtils.log("Joined room \(token) in NC successfully")
|
||||
|
||||
guard let extSignalingController = NCSettingsController.sharedInstance().externalSignalingController(forAccountId: activeAccount.accountId)
|
||||
else {
|
||||
// Joined room in NC successfully and no external signaling server configured.
|
||||
completionBlock(sessionId, room, nil, 0, nil)
|
||||
return
|
||||
}
|
||||
|
||||
NCUtils.log("Trying to join room \(token) in external signaling server...")
|
||||
|
||||
// Remember the latest sessionId we're using to join a room, to be able to check when joining the external signaling server
|
||||
self.joiningSessionId = sessionId
|
||||
|
||||
self.getSignalingSettingsHelper(for: activeAccount, forRoom: token) { signalingSettings in
|
||||
self.getExternalSignalingHelper(for: activeAccount, forRoom: token) { extSignalingController, signalingSettings, error in
|
||||
guard error == nil else {
|
||||
// There was an error to ensure we have the correct signaling settings for joining a federated conversation
|
||||
completionBlock(nil, nil, nil, NCRoomsManager.statusCodeFailedToJoinExternal, nil)
|
||||
return
|
||||
}
|
||||
|
||||
guard let extSignalingController else {
|
||||
// Joined room in NC successfully and no external signaling server configured.
|
||||
completionBlock(sessionId, room, nil, 0, nil)
|
||||
return
|
||||
}
|
||||
|
||||
NCUtils.log("Trying to join room \(token) in external signaling server...")
|
||||
|
||||
let federation = signalingSettings?.getFederationJoinDictionary()
|
||||
|
||||
extSignalingController.joinRoom(token, withSessionId: sessionId, withFederation: federation) { error in
|
||||
|
@ -192,18 +204,36 @@ import Foundation
|
|||
})
|
||||
}
|
||||
|
||||
private func getSignalingSettingsHelper(for account: TalkAccount, forRoom token: String, withCompletion completion: @escaping (SignalingSettings?) -> Void) {
|
||||
// Currently we only need the signaling settings in case the room supports federation-v2
|
||||
if let room = NCDatabaseManager.sharedInstance().room(withToken: token, forAccountId: account.accountId), room.supportsFederatedCalling {
|
||||
NCAPIController.sharedInstance().getSignalingSettings(for: account, forRoom: token) { signalingSettings, _ in
|
||||
completion(signalingSettings)
|
||||
private func getExternalSignalingHelper(for account: TalkAccount, forRoom token: String, withCompletion completion: @escaping (NCExternalSignalingController?, SignalingSettings?, Error?) -> Void) {
|
||||
let room = NCDatabaseManager.sharedInstance().room(withToken: token, forAccountId: account.accountId)
|
||||
|
||||
guard room?.supportsFederatedCalling ?? false else {
|
||||
// No federated room -> just ensure that we have a signaling configuration and a potential external signaling controller
|
||||
NCSettingsController.sharedInstance().ensureSignalingConfiguration(forAccountId: account.accountId, with: nil) { extSignalingController in
|
||||
completion(extSignalingController, nil, nil)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// This is a federated conversation (with federated calling supported), so we require signaling settings for joining
|
||||
// the external signaling controller
|
||||
NCAPIController.sharedInstance().getSignalingSettings(for: account, forRoom: token) { signalingSettings, _ in
|
||||
guard let signalingSettings else {
|
||||
// We need to fail if we are unable to get signaling settings for a federation conversation
|
||||
completion(nil, nil, NSError(domain: NSCocoaErrorDomain, code: 0))
|
||||
return
|
||||
}
|
||||
|
||||
NCSettingsController.sharedInstance().ensureSignalingConfiguration(forAccountId: account.accountId, with: signalingSettings) { extSignalingController in
|
||||
completion(extSignalingController, signalingSettings, nil)
|
||||
}
|
||||
} else {
|
||||
completion(nil)
|
||||
}
|
||||
}
|
||||
|
||||
public func rejoinRoom(_ token: String, completionBlock: @escaping (_ sessionId: String?, _ room: NCRoom?, _ error: Error?, _ statusCode: Int, _ statusReason: String?) -> Void) {
|
||||
public func rejoinRoomForCall(_ token: String, completionBlock: @escaping (_ sessionId: String?, _ room: NCRoom?, _ error: Error?, _ statusCode: Int, _ statusReason: String?) -> Void) {
|
||||
NCUtils.log("Rejoining room \(token)")
|
||||
|
||||
guard let roomController = self.activeRooms[token] as? NCRoomController else { return }
|
||||
|
||||
let activeAccount = NCDatabaseManager.sharedInstance().activeAccount()
|
||||
|
@ -212,16 +242,21 @@ import Foundation
|
|||
self.joinRoomTask = NCAPIController.sharedInstance().joinRoom(token, for: activeAccount, withCompletionBlock: { sessionId, room, error, statusCode, statusReason in
|
||||
if error == nil {
|
||||
roomController.userSessionId = sessionId
|
||||
roomController.inChat = true
|
||||
roomController.inCall = true
|
||||
|
||||
guard let extSignalingController = NCSettingsController.sharedInstance().externalSignalingController(forAccountId: activeAccount.accountId)
|
||||
else {
|
||||
// Joined room in NC successfully and no external signaling server configured.
|
||||
completionBlock(sessionId, room, nil, 0, nil)
|
||||
return
|
||||
}
|
||||
self.getExternalSignalingHelper(for: activeAccount, forRoom: token) { extSignalingController, signalingSettings, error in
|
||||
guard error == nil else {
|
||||
// There was an error to ensure we have the correct signaling settings for joining a federated conversation
|
||||
completionBlock(nil, nil, nil, NCRoomsManager.statusCodeFailedToJoinExternal, nil)
|
||||
return
|
||||
}
|
||||
|
||||
guard let extSignalingController else {
|
||||
// Joined room in NC successfully and no external signaling server configured.
|
||||
completionBlock(sessionId, room, nil, 0, nil)
|
||||
return
|
||||
}
|
||||
|
||||
self.getSignalingSettingsHelper(for: activeAccount, forRoom: token) { signalingSettings in
|
||||
let federation = signalingSettings?.getFederationJoinDictionary()
|
||||
|
||||
extSignalingController.joinRoom(token, withSessionId: sessionId, withFederation: federation) { error in
|
||||
|
@ -247,6 +282,8 @@ import Foundation
|
|||
public func leaveRoom(_ token: String) {
|
||||
// Check if leaving the room we are joining
|
||||
if self.isJoiningRoom(withToken: token) {
|
||||
NCUtils.log("Leaving room \(token), but still joining -> cancel")
|
||||
|
||||
self.joiningRoomToken = nil
|
||||
self.joiningSessionId = nil
|
||||
self.joinRoomTask?.cancel()
|
||||
|
|
|
@ -29,19 +29,21 @@ extern NSString * const kUserProfileScopePublished;
|
|||
|
||||
extern NSString * const NCSettingsControllerDidChangeActiveAccountNotification;
|
||||
|
||||
@class NCExternalSignalingController;
|
||||
@class SignalingSettings;
|
||||
|
||||
typedef void (^UpdatedProfileCompletionBlock)(NSError *error);
|
||||
typedef void (^LogoutCompletionBlock)(NSError *error);
|
||||
typedef void (^GetCapabilitiesCompletionBlock)(NSError *error);
|
||||
typedef void (^GetSignalingConfigCompletionBlock)(NSError *error);
|
||||
typedef void (^UpdateSignalingConfigCompletionBlock)(NCExternalSignalingController * _Nullable signalingServer, NSError * _Nullable error);
|
||||
typedef void (^SubscribeForPushNotificationsCompletionBlock)(BOOL success);
|
||||
typedef void (^EnsureSignalingConfigCompletionBlock)(NCExternalSignalingController * _Nullable signalingServer);
|
||||
|
||||
typedef NS_ENUM(NSInteger, NCPreferredFileSorting) {
|
||||
NCAlphabeticalSorting = 1,
|
||||
NCModificationDateSorting
|
||||
};
|
||||
|
||||
@class NCExternalSignalingController;
|
||||
|
||||
@interface NCSettingsController : NSObject
|
||||
|
||||
@property (nonatomic, copy) ARDSettingsModel *videoSettingsModel;
|
||||
|
@ -56,9 +58,10 @@ typedef NS_ENUM(NSInteger, NCPreferredFileSorting) {
|
|||
- (void)getUserProfileForAccountId:(NSString *)accountId withCompletionBlock:(UpdatedProfileCompletionBlock)block;
|
||||
- (void)logoutAccountWithAccountId:(NSString *)accountId withCompletionBlock:(LogoutCompletionBlock)block;
|
||||
- (void)getCapabilitiesForAccountId:(NSString *)accountId withCompletionBlock:(GetCapabilitiesCompletionBlock)block;
|
||||
- (void)getSignalingConfigurationForAccountId:(NSString *)accountId withCompletionBlock:(GetSignalingConfigCompletionBlock)block;
|
||||
- (void)setSignalingConfigurationForAccountId:(NSString *)accountId;
|
||||
- (NCExternalSignalingController *)externalSignalingControllerForAccountId:(NSString *)accountId;
|
||||
- (void)updateSignalingConfigurationForAccountId:(NSString * _Nonnull)accountId withCompletionBlock:(UpdateSignalingConfigCompletionBlock _Nonnull)block;
|
||||
- (NCExternalSignalingController * _Nullable)setSignalingConfigurationForAccountId:(NSString * _Nonnull)accountId withSettings:(SignalingSettings * _Nonnull)settings;
|
||||
- (void)ensureSignalingConfigurationForAccountId:(NSString * _Nonnull)accountId withSettings:(SignalingSettings * _Nullable)settings withCompletionBlock:(EnsureSignalingConfigCompletionBlock _Nonnull)block;
|
||||
- (NCExternalSignalingController * _Nullable)externalSignalingControllerForAccountId:(NSString * _Nonnull)accountId;
|
||||
- (void)connectDisconnectedExternalSignalingControllers;
|
||||
- (void)disconnectAllExternalSignalingControllers;
|
||||
- (void)subscribeForPushNotificationsForAccountId:(NSString *)accountId withCompletionBlock:(SubscribeForPushNotificationsCompletionBlock)block;
|
||||
|
|
|
@ -88,7 +88,7 @@ NSString * const kDidReceiveCallsFromOldAccount = @"receivedCallsFromOldAccount"
|
|||
_videoSettingsModel = [[ARDSettingsModel alloc] init];
|
||||
_signalingConfigurations = [NSMutableDictionary new];
|
||||
_externalSignalingControllers = [NSMutableDictionary new];
|
||||
|
||||
|
||||
[self configureDatabase];
|
||||
[self checkStoredDataInKechain];
|
||||
|
||||
|
@ -276,22 +276,18 @@ NSString * const kDidReceiveCallsFromOldAccount = @"receivedCallsFromOldAccount"
|
|||
return;
|
||||
}
|
||||
|
||||
[[NCSettingsController sharedInstance] getCapabilitiesForAccountId:accountId withCompletionBlock:^(NSError *error) {
|
||||
[self getCapabilitiesForAccountId:accountId withCompletionBlock:^(NSError *error) {
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
|
||||
[[NCSettingsController sharedInstance] getSignalingConfigurationForAccountId:accountId withCompletionBlock:^(NSError *error) {
|
||||
if (error) {
|
||||
return;
|
||||
BGTaskHelper *bgTask = [BGTaskHelper startBackgroundTaskWithName:@"NCUpdateSignalingConfiguration" expirationHandler:nil];
|
||||
|
||||
[self updateSignalingConfigurationForAccountId:accountId withCompletionBlock:^(NCExternalSignalingController * _Nullable signalingServer, NSError *error) {
|
||||
if (!error) {
|
||||
[[NCDatabaseManager sharedInstance] updateTalkConfigurationHashForAccountId:accountId withHash:configurationHash];
|
||||
}
|
||||
|
||||
BGTaskHelper *bgTask = [BGTaskHelper startBackgroundTaskWithName:@"NCUpdateSignalingConfiguration" expirationHandler:nil];
|
||||
|
||||
// SetSignalingConfiguration should be called just once
|
||||
[[NCSettingsController sharedInstance] setSignalingConfigurationForAccountId:accountId];
|
||||
[[NCDatabaseManager sharedInstance] updateTalkConfigurationHashForAccountId:accountId withHash:configurationHash];
|
||||
|
||||
[bgTask stopBackgroundTask];
|
||||
}];
|
||||
}];
|
||||
|
@ -461,14 +457,14 @@ NSString * const kDidReceiveCallsFromOldAccount = @"receivedCallsFromOldAccount"
|
|||
|
||||
#pragma mark - Signaling Configuration
|
||||
|
||||
- (void)getSignalingConfigurationForAccountId:(NSString *)accountId withCompletionBlock:(GetSignalingConfigCompletionBlock)block
|
||||
- (void)updateSignalingConfigurationForAccountId:(NSString *)accountId withCompletionBlock:(UpdateSignalingConfigCompletionBlock)block
|
||||
{
|
||||
TalkAccount *account = [[NCDatabaseManager sharedInstance] talkAccountForAccountId:accountId];
|
||||
|
||||
if (!account) {
|
||||
if (block) {
|
||||
NSError *error = [NSError errorWithDomain:NSCocoaErrorDomain code:0 userInfo:nil];
|
||||
block(error);
|
||||
block(nil, error);
|
||||
}
|
||||
|
||||
return;
|
||||
|
@ -477,46 +473,70 @@ NSString * const kDidReceiveCallsFromOldAccount = @"receivedCallsFromOldAccount"
|
|||
[[NCAPIController sharedInstance] getSignalingSettingsFor:account forRoom:nil completionBlock:^(SignalingSettings * _Nullable settings, NSError * _Nullable error) {
|
||||
if (!error) {
|
||||
if (settings && account && account.accountId) {
|
||||
[self->_signalingConfigurations setObject:settings forKey:account.accountId];
|
||||
NCExternalSignalingController *extSignalingController = [self setSignalingConfigurationForAccountId:account.accountId withSettings:settings];
|
||||
|
||||
if (block) {
|
||||
block(nil);
|
||||
block(extSignalingController, nil);
|
||||
}
|
||||
} else {
|
||||
NSError *error = [NSError errorWithDomain:NSCocoaErrorDomain code:0 userInfo:nil];
|
||||
|
||||
if (block) {
|
||||
block(error);
|
||||
block(nil, error);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
NSLog(@"Error while getting signaling configuration");
|
||||
if (block) block(error);
|
||||
if (block) {
|
||||
block(nil, error);
|
||||
}
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
// SetSignalingConfiguration should be called just once
|
||||
- (void)setSignalingConfigurationForAccountId:(NSString *)accountId
|
||||
- (NCExternalSignalingController * _Nullable)setSignalingConfigurationForAccountId:(NSString *)accountId withSettings:(SignalingSettings * _Nonnull)signalingSettings
|
||||
{
|
||||
SignalingSettings *signalingSettings = [_signalingConfigurations objectForKey:accountId];
|
||||
[self->_signalingConfigurations setObject:signalingSettings forKey:accountId];
|
||||
|
||||
if (signalingSettings.server && signalingSettings.server.length > 0 && signalingSettings.ticket && signalingSettings.ticket.length > 0) {
|
||||
BGTaskHelper *bgTask = [BGTaskHelper startBackgroundTaskWithName:@"NCSetSignalingConfiguration" expirationHandler:nil];
|
||||
NCExternalSignalingController *extSignalingController = [self->_externalSignalingControllers objectForKey:accountId];
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
NCExternalSignalingController *extSignalingController = [self->_externalSignalingControllers objectForKey:accountId];
|
||||
|
||||
if (extSignalingController) {
|
||||
[extSignalingController disconnect];
|
||||
}
|
||||
|
||||
TalkAccount *account = [[NCDatabaseManager sharedInstance] talkAccountForAccountId:accountId];
|
||||
extSignalingController = [[NCExternalSignalingController alloc] initWithAccount:account server:signalingSettings.server andTicket:signalingSettings.ticket];
|
||||
[self->_externalSignalingControllers setObject:extSignalingController forKey:accountId];
|
||||
if (extSignalingController) {
|
||||
[extSignalingController disconnect];
|
||||
}
|
||||
|
||||
[bgTask stopBackgroundTask];
|
||||
});
|
||||
TalkAccount *account = [[NCDatabaseManager sharedInstance] talkAccountForAccountId:accountId];
|
||||
extSignalingController = [[NCExternalSignalingController alloc] initWithAccount:account server:signalingSettings.server andTicket:signalingSettings.ticket];
|
||||
[self->_externalSignalingControllers setObject:extSignalingController forKey:accountId];
|
||||
|
||||
[bgTask stopBackgroundTask];
|
||||
|
||||
return extSignalingController;
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)ensureSignalingConfigurationForAccountId:(NSString *)accountId withSettings:(SignalingSettings *)settings withCompletionBlock:(EnsureSignalingConfigCompletionBlock)block
|
||||
{
|
||||
SignalingSettings *currentSignalingSettings = [_signalingConfigurations objectForKey:accountId];
|
||||
|
||||
if (currentSignalingSettings) {
|
||||
block([self->_externalSignalingControllers objectForKey:accountId]);
|
||||
} else {
|
||||
[NCUtils log:@"Ensure signaling configuration -> Setting configuration"];
|
||||
|
||||
if (settings) {
|
||||
// In case settings are provided, we use these provided settings
|
||||
NCExternalSignalingController *extSignalingController = [self setSignalingConfigurationForAccountId:accountId withSettings:settings];
|
||||
block(extSignalingController);
|
||||
} else {
|
||||
// There were no settings provided for that call, we have to update the settings
|
||||
[self updateSignalingConfigurationForAccountId:accountId withCompletionBlock:^(NCExternalSignalingController * _Nullable signalingServer, NSError *error) {
|
||||
block(signalingServer);
|
||||
}];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче