зеркало из https://github.com/nextcloud/talk-ios.git
546 строки
22 KiB
Objective-C
546 строки
22 KiB
Objective-C
/**
|
|
* @copyright Copyright (c) 2020 Ivan Sein <ivan@nextcloud.com>
|
|
*
|
|
* @author Ivan Sein <ivan@nextcloud.com>
|
|
*
|
|
* @license GNU GPL version 3 or any later version
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
#import "CallKitManager.h"
|
|
#import <CallKit/CXError.h>
|
|
|
|
#import "CallConstants.h"
|
|
#import "NCAudioController.h"
|
|
#import "NCAPIController.h"
|
|
#import "NCAppBranding.h"
|
|
#import "NCDatabaseManager.h"
|
|
#import "NCNotificationController.h"
|
|
#import "NCRoomsManager.h"
|
|
#import "NCSettingsController.h"
|
|
#import "NCUserInterfaceController.h"
|
|
|
|
NSString * const CallKitManagerDidAnswerCallNotification = @"CallKitManagerDidAnswerCallNotification";
|
|
NSString * const CallKitManagerDidEndCallNotification = @"CallKitManagerDidEndCallNotification";
|
|
NSString * const CallKitManagerDidStartCallNotification = @"CallKitManagerDidStartCallNotification";
|
|
NSString * const CallKitManagerDidChangeAudioMuteNotification = @"CallKitManagerDidChangeAudioMuteNotification";
|
|
NSString * const CallKitManagerWantsToUpgradeToVideoCall = @"CallKitManagerWantsToUpgradeToVideoCall";
|
|
|
|
NSTimeInterval const kCallKitManagerMaxRingingTimeSeconds = 45.0;
|
|
NSTimeInterval const kCallKitManagerCheckCallStateEverySeconds = 3.0;
|
|
|
|
@interface CallKitManager () <CXProviderDelegate>
|
|
|
|
@property (nonatomic, strong) CXProvider *provider;
|
|
@property (nonatomic, strong) CXCallController *callController;
|
|
@property (nonatomic, strong) NSMutableDictionary *hangUpTimers; // uuid -> hangUpTimer
|
|
@property (nonatomic, strong) NSMutableDictionary *callStateTimers; // uuid -> callStateTimer
|
|
|
|
@end
|
|
|
|
@implementation CallKitCall
|
|
@end
|
|
|
|
@implementation CallKitManager
|
|
|
|
+ (CallKitManager *)sharedInstance
|
|
{
|
|
static CallKitManager *sharedInstance = nil;
|
|
static dispatch_once_t onceToken;
|
|
dispatch_once(&onceToken, ^{
|
|
sharedInstance = [[CallKitManager alloc] init];
|
|
[sharedInstance provider];
|
|
});
|
|
return sharedInstance;
|
|
}
|
|
|
|
- (id)init
|
|
{
|
|
self = [super init];
|
|
if (self) {
|
|
self.calls = [[NSMutableDictionary alloc] init];
|
|
self.hangUpTimers = [[NSMutableDictionary alloc] init];
|
|
self.callStateTimers = [[NSMutableDictionary alloc] init];
|
|
}
|
|
return self;
|
|
}
|
|
|
|
+ (BOOL)isCallKitAvailable
|
|
{
|
|
// CallKit should be deactivated in China as requested by Apple
|
|
return ![NSLocale.currentLocale.countryCode isEqual: @"CN"];
|
|
}
|
|
|
|
#pragma mark - Getters
|
|
|
|
- (CXProvider *)provider
|
|
{
|
|
if (!_provider) {
|
|
CXProviderConfiguration *configuration = [[CXProviderConfiguration alloc] initWithLocalizedName:talkAppName];
|
|
configuration.supportsVideo = YES;
|
|
configuration.maximumCallGroups = 1;
|
|
configuration.maximumCallsPerCallGroup = 1;
|
|
configuration.supportedHandleTypes = [NSSet setWithObjects:@(CXHandleTypePhoneNumber), @(CXHandleTypeEmailAddress), @(CXHandleTypeGeneric), nil];
|
|
configuration.iconTemplateImageData = UIImagePNGRepresentation([UIImage imageNamed:@"app-logo-callkit"]);
|
|
_provider = [[CXProvider alloc] initWithConfiguration:configuration];
|
|
[_provider setDelegate:self queue:nil];
|
|
}
|
|
return _provider;
|
|
}
|
|
|
|
- (CXCallController *)callController
|
|
{
|
|
if (!_callController) {
|
|
_callController = [[CXCallController alloc] init];
|
|
}
|
|
return _callController;
|
|
}
|
|
|
|
#pragma mark - Utils
|
|
|
|
- (CXCallUpdate *)defaultCallUpdate
|
|
{
|
|
CXCallUpdate *update = [[CXCallUpdate alloc] init];
|
|
update.supportsHolding = NO;
|
|
update.supportsGrouping = NO;
|
|
update.supportsUngrouping = NO;
|
|
update.supportsDTMF = NO;
|
|
update.hasVideo = NO;
|
|
|
|
return update;
|
|
}
|
|
|
|
- (CallKitCall *)callForToken:(NSString *)token
|
|
{
|
|
for (CallKitCall *call in [_calls allValues]) {
|
|
if ([call.token isEqualToString:token]) {
|
|
return call;
|
|
}
|
|
}
|
|
|
|
return nil;;
|
|
}
|
|
|
|
#pragma mark - Actions
|
|
|
|
- (void)reportIncomingCall:(NSString *)token withDisplayName:(NSString *)displayName forAccountId:(NSString *)accountId
|
|
{
|
|
BOOL ongoingCalls = _calls.count > 0;
|
|
TalkAccount *activeAccount = [[NCDatabaseManager sharedInstance] activeAccount];
|
|
|
|
// If the app is not active (e.g. in background) and there is an open chat
|
|
BOOL isAppActive = [[UIApplication sharedApplication] applicationState] == UIApplicationStateActive;
|
|
NCChatViewController *chatViewController = [[NCRoomsManager sharedInstance] chatViewController];
|
|
if (!isAppActive && chatViewController) {
|
|
// Leave the chat so it doesn't try to join the chat conversation when the app becomes active.
|
|
[chatViewController leaveChat];
|
|
[[NCUserInterfaceController sharedInstance] presentConversationsList];
|
|
}
|
|
|
|
// If the incoming call is from a different account
|
|
if (![activeAccount.accountId isEqualToString:accountId]) {
|
|
// If there is an ongoing call then show a local notification
|
|
if (ongoingCalls) {
|
|
[self reportAndCancelIncomingCall:token withDisplayName:displayName forAccountId:accountId];
|
|
return;
|
|
// Change accounts if there are no ongoing calls
|
|
} else {
|
|
[[NCSettingsController sharedInstance] setActiveAccountWithAccountId:accountId];
|
|
}
|
|
}
|
|
|
|
CXCallUpdate *update = [self defaultCallUpdate];
|
|
update.remoteHandle = [[CXHandle alloc] initWithType:CXHandleTypeGeneric value:token];
|
|
update.localizedCallerName = displayName;
|
|
|
|
NSUUID *callUUID = [NSUUID new];
|
|
CallKitCall *call = [[CallKitCall alloc] init];
|
|
call.uuid = callUUID;
|
|
call.token = token;
|
|
call.displayName = displayName;
|
|
call.accountId = accountId;
|
|
call.update = update;
|
|
call.reportedWhileInCall = ongoingCalls;
|
|
call.isRinging = YES;
|
|
|
|
__weak CallKitManager *weakSelf = self;
|
|
[self.provider reportNewIncomingCallWithUUID:callUUID update:update completion:^(NSError * _Nullable error) {
|
|
if (!error) {
|
|
// Add call to calls array
|
|
[weakSelf.calls setObject:call forKey:callUUID];
|
|
|
|
// Add hangUpTimer to timers array
|
|
NSTimer *hangUpTimer = [NSTimer scheduledTimerWithTimeInterval:kCallKitManagerMaxRingingTimeSeconds target:self selector:@selector(endCallWithMissedCallNotification:) userInfo:call repeats:NO];
|
|
[weakSelf.hangUpTimers setObject:hangUpTimer forKey:callUUID];
|
|
|
|
// Add callStateTimer to timers array
|
|
NSTimer *callStateTimer = [NSTimer scheduledTimerWithTimeInterval:kCallKitManagerCheckCallStateEverySeconds target:self selector:@selector(checkCallStateForCall:) userInfo:call repeats:NO];
|
|
[weakSelf.callStateTimers setObject:callStateTimer forKey:callUUID];
|
|
|
|
// Get call info from server
|
|
[weakSelf getCallInfoForCall:call];
|
|
} else {
|
|
NSLog(@"Provider could not present incoming call view.");
|
|
}
|
|
}];
|
|
}
|
|
|
|
- (void)reportAndCancelIncomingCall:(NSString *)token withDisplayName:(NSString *)displayName forAccountId:(NSString *)accountId
|
|
{
|
|
CXCallUpdate *update = [self defaultCallUpdate];
|
|
NSUUID *callUUID = [NSUUID new];
|
|
CallKitCall *call = [[CallKitCall alloc] init];
|
|
call.uuid = callUUID;
|
|
call.token = token;
|
|
call.accountId = accountId;
|
|
call.update = update;
|
|
__weak CallKitManager *weakSelf = self;
|
|
[self.provider reportNewIncomingCallWithUUID:callUUID update:update completion:^(NSError * _Nullable error) {
|
|
if (!error) {
|
|
[weakSelf.calls setObject:call forKey:callUUID];
|
|
NSMutableDictionary *userInfo = [NSMutableDictionary dictionaryWithObject:call.token forKey:@"roomToken"];
|
|
[userInfo setValue:@(kNCLocalNotificationTypeCancelledCall) forKey:@"localNotificationType"];
|
|
[userInfo setObject:call.accountId forKey:@"accountId"];
|
|
[[NCNotificationController sharedInstance] showLocalNotification:kNCLocalNotificationTypeCancelledCall withUserInfo:userInfo];
|
|
[weakSelf endCallWithUUID:callUUID];
|
|
} else {
|
|
NSLog(@"Provider could not present incoming call view.");
|
|
}
|
|
}];
|
|
}
|
|
|
|
- (void)reportIncomingCallForNonCallKitDevicesWithPushNotification:(NCPushNotification *)pushNotification
|
|
{
|
|
CXCallUpdate *update = [self defaultCallUpdate];
|
|
NSUUID *callUUID = [NSUUID new];
|
|
CallKitCall *call = [[CallKitCall alloc] init];
|
|
call.uuid = callUUID;
|
|
call.token = pushNotification.roomToken;
|
|
call.accountId = pushNotification.accountId;
|
|
call.update = update;
|
|
__weak CallKitManager *weakSelf = self;
|
|
[self.provider reportNewIncomingCallWithUUID:callUUID update:update completion:^(NSError * _Nullable error) {
|
|
if (!error) {
|
|
[weakSelf.calls setObject:call forKey:callUUID];
|
|
[[NCNotificationController sharedInstance] showLocalNotificationForIncomingCallWithPushNotificaion:pushNotification];
|
|
[weakSelf endCallWithUUID:callUUID];
|
|
} else {
|
|
NSLog(@"Provider could not present incoming call view.");
|
|
}
|
|
}];
|
|
}
|
|
|
|
- (void)getCallInfoForCall:(CallKitCall *)call
|
|
{
|
|
NCRoom *room = [[NCRoomsManager sharedInstance] roomWithToken:call.token forAccountId:call.accountId];
|
|
if (room) {
|
|
[self updateCall:call withDisplayName:room.displayName];
|
|
}
|
|
|
|
TalkAccount *account = [[NCDatabaseManager sharedInstance] talkAccountForAccountId:call.accountId];
|
|
[[NCAPIController sharedInstance] getRoomForAccount:account withToken:call.token withCompletionBlock:^(NSDictionary *roomDict, NSError *error) {
|
|
if (!error) {
|
|
NCRoom *room = [NCRoom roomWithDictionary:roomDict andAccountId:call.accountId];
|
|
[self updateCall:call withDisplayName:room.displayName];
|
|
|
|
if ([[NCDatabaseManager sharedInstance] serverHasTalkCapability:kCapabilityCallFlags forAccountId:call.accountId]) {
|
|
NSInteger callFlag = [[roomDict objectForKey:@"callFlag"] integerValue];
|
|
if (callFlag == CallFlagDisconnected) {
|
|
[self presentMissedCallNotificationForCall:call];
|
|
[self endCallWithUUID:call.uuid];
|
|
} else if ((callFlag & CallFlagWithVideo) != 0) {
|
|
[self updateCall:call hasVideo:YES];
|
|
}
|
|
}
|
|
}
|
|
}];
|
|
}
|
|
|
|
- (void)updateCall:(CallKitCall *)call withDisplayName:(NSString *)displayName
|
|
{
|
|
call.displayName = displayName;
|
|
call.update.localizedCallerName = displayName;
|
|
|
|
[self.provider reportCallWithUUID:call.uuid updated:call.update];
|
|
}
|
|
|
|
- (void)updateCall:(CallKitCall *)call hasVideo:(BOOL)hasVideo
|
|
{
|
|
call.update.hasVideo = hasVideo;
|
|
|
|
[self.provider reportCallWithUUID:call.uuid updated:call.update];
|
|
}
|
|
|
|
- (void)stopHangUpTimerForCallUUID:(NSUUID *)uuid
|
|
{
|
|
NSTimer *hangUpTimer = [_hangUpTimers objectForKey:uuid];
|
|
if (hangUpTimer) {
|
|
[hangUpTimer invalidate];
|
|
[_hangUpTimers removeObjectForKey:uuid];
|
|
}
|
|
}
|
|
|
|
- (void)stopCallStateTimerForCallUUID:(NSUUID *)uuid
|
|
{
|
|
NSTimer *callStateTimer = [_callStateTimers objectForKey:uuid];
|
|
if (callStateTimer) {
|
|
[callStateTimer invalidate];
|
|
[_callStateTimers removeObjectForKey:uuid];
|
|
}
|
|
}
|
|
|
|
- (void)endCallWithMissedCallNotification:(NSTimer*)timer
|
|
{
|
|
CallKitCall *call = [timer userInfo];
|
|
[self presentMissedCallNotificationForCall:call];
|
|
[self endCallWithUUID:call.uuid];
|
|
}
|
|
|
|
- (void)presentMissedCallNotificationForCall:(CallKitCall *)call
|
|
{
|
|
if (call) {
|
|
NSMutableDictionary *userInfo = [NSMutableDictionary dictionaryWithObject:call.token forKey:@"roomToken"];
|
|
[userInfo setValue:call.displayName forKey:@"displayName"];
|
|
[userInfo setValue:@(kNCLocalNotificationTypeMissedCall) forKey:@"localNotificationType"];
|
|
[userInfo setObject:call.accountId forKey:@"accountId"];
|
|
[[NCNotificationController sharedInstance] showLocalNotification:kNCLocalNotificationTypeMissedCall withUserInfo:userInfo];
|
|
}
|
|
}
|
|
|
|
- (void)checkCallStateForCall:(NSTimer *)timer
|
|
{
|
|
CallKitCall *call = [timer userInfo];
|
|
if (!call) {
|
|
return;
|
|
}
|
|
|
|
__weak CallKitManager *weakSelf = self;
|
|
TalkAccount *account = [[NCDatabaseManager sharedInstance] talkAccountForAccountId:call.accountId];
|
|
[[NCAPIController sharedInstance] getParticipantsFromRoom:call.token forAccount:account withCompletionBlock:^(NSMutableArray *participants, NSError *error) {
|
|
// Make sure call is still ringing at this point to avoid a race-condition between answering the call on this device and the API callback
|
|
if (!call.isRinging) {
|
|
return;
|
|
}
|
|
|
|
BOOL isAnyoneInCall = NO;
|
|
for (NCRoomParticipant *participant in participants) {
|
|
if ([account.userId isEqualToString:participant.participantId] && participant.inCall) {
|
|
// Account is already in a call (answered the call on a different device) -> no need to keep ringing
|
|
[self endCallWithUUID:call.uuid];
|
|
return;
|
|
}
|
|
if (participant.inCall) {
|
|
isAnyoneInCall = YES;
|
|
}
|
|
}
|
|
|
|
if (!isAnyoneInCall) {
|
|
// No one is in the call, we can hang up and show missed call notification
|
|
[self presentMissedCallNotificationForCall:call];
|
|
[self endCallWithUUID:call.uuid];
|
|
return;
|
|
}
|
|
|
|
// Reschedule next check
|
|
NSTimer *callStateTimer = [NSTimer scheduledTimerWithTimeInterval:kCallKitManagerCheckCallStateEverySeconds target:self selector:@selector(checkCallStateForCall:) userInfo:call repeats:NO];
|
|
[weakSelf.callStateTimers setObject:callStateTimer forKey:call.uuid];
|
|
|
|
}];
|
|
}
|
|
|
|
- (void)startCall:(NSString *)token withVideoEnabled:(BOOL)videoEnabled andDisplayName:(NSString *)displayName withAccountId:(NSString *)accountId
|
|
{
|
|
if (![CallKitManager isCallKitAvailable]) {
|
|
NSMutableDictionary *userInfo = [NSMutableDictionary dictionaryWithObject:token forKey:@"roomToken"];
|
|
[userInfo setValue:@(videoEnabled) forKey:@"isVideoEnabled"];
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:CallKitManagerDidStartCallNotification
|
|
object:self
|
|
userInfo:userInfo];
|
|
return;
|
|
}
|
|
|
|
// Start a new call
|
|
if (_calls.count == 0) {
|
|
CXCallUpdate *update = [self defaultCallUpdate];
|
|
CXHandle *handle = [[CXHandle alloc] initWithType:CXHandleTypeGeneric value:token];
|
|
update.remoteHandle = handle;
|
|
update.localizedCallerName = displayName;
|
|
update.hasVideo = videoEnabled;
|
|
|
|
NSUUID *callUUID = [NSUUID new];
|
|
CallKitCall *call = [[CallKitCall alloc] init];
|
|
call.uuid = callUUID;
|
|
call.token = token;
|
|
call.displayName = displayName;
|
|
call.accountId = accountId;
|
|
call.update = update;
|
|
|
|
CXStartCallAction *startCallAction = [[CXStartCallAction alloc] initWithCallUUID:callUUID handle:handle];
|
|
startCallAction.video = videoEnabled;
|
|
startCallAction.contactIdentifier = displayName;
|
|
CXTransaction *transaction = [[CXTransaction alloc] init];
|
|
[transaction addAction:startCallAction];
|
|
|
|
__weak CallKitManager *weakSelf = self;
|
|
[self.callController requestTransaction:transaction completion:^(NSError * _Nullable error) {
|
|
if (!error) {
|
|
[weakSelf.calls setObject:call forKey:callUUID];
|
|
} else {
|
|
NSLog(@"%@", error.localizedDescription);
|
|
}
|
|
}];
|
|
// Send notification for video call upgrade.
|
|
// Since we send the token in the notification, it will only ask
|
|
// for an upgrade if there is an ongoing (audioOnly) call in that room.
|
|
} else if (videoEnabled) {
|
|
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:token forKey:@"roomToken"];
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:CallKitManagerWantsToUpgradeToVideoCall
|
|
object:self
|
|
userInfo:userInfo];
|
|
}
|
|
}
|
|
|
|
- (void)endCall:(NSString *)token
|
|
{
|
|
CallKitCall *call = [self callForToken:token];
|
|
if (call) {
|
|
[self endCallWithUUID:call.uuid];
|
|
}
|
|
}
|
|
|
|
- (void)endCallWithUUID:(NSUUID *)uuid
|
|
{
|
|
CallKitCall *call = [_calls objectForKey:uuid];
|
|
if (call) {
|
|
CXEndCallAction *endCallAction = [[CXEndCallAction alloc] initWithCallUUID:call.uuid];
|
|
CXTransaction *transaction = [[CXTransaction alloc] init];
|
|
[transaction addAction:endCallAction];
|
|
[self.callController requestTransaction:transaction completion:^(NSError * _Nullable error) {
|
|
if (error) {
|
|
NSLog(@"%@", error.localizedDescription);
|
|
}
|
|
}];
|
|
}
|
|
}
|
|
|
|
- (void)reportAudioMuted:(BOOL)muted forCall:(NSString *)token
|
|
{
|
|
CallKitCall *call = [self callForToken:token];
|
|
if (call) {
|
|
CXSetMutedCallAction *muteAction = [[CXSetMutedCallAction alloc] initWithCallUUID:call.uuid muted:muted];
|
|
CXTransaction *transaction = [[CXTransaction alloc] init];
|
|
[transaction addAction:muteAction];
|
|
[self.callController requestTransaction:transaction completion:^(NSError * _Nullable error) {
|
|
if (error) {
|
|
NSLog(@"%@", error.localizedDescription);
|
|
}
|
|
}];
|
|
}
|
|
}
|
|
|
|
#pragma mark - CXProviderDelegate
|
|
|
|
- (void)providerDidReset:(CXProvider *)provider
|
|
{
|
|
NSLog(@"Provider:didReset");
|
|
}
|
|
|
|
- (void)provider:(CXProvider *)provider performStartCallAction:(nonnull CXStartCallAction *)action
|
|
{
|
|
CallKitCall *call = [_calls objectForKey:action.callUUID];
|
|
if (call) {
|
|
// Seems to be needed to display the call name correctly
|
|
[_provider reportCallWithUUID:call.uuid updated:call.update];
|
|
|
|
// Report outgoing call
|
|
[provider reportOutgoingCallWithUUID:action.callUUID connectedAtDate:[NSDate new]];
|
|
NSMutableDictionary *userInfo = [NSMutableDictionary dictionaryWithObject:action.handle.value forKey:@"roomToken"];
|
|
[userInfo setValue:@(action.isVideo) forKey:@"isVideoEnabled"];
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:CallKitManagerDidStartCallNotification
|
|
object:self
|
|
userInfo:userInfo];
|
|
}
|
|
|
|
[action fulfill];
|
|
}
|
|
|
|
- (void)provider:(CXProvider *)provider performAnswerCallAction:(CXAnswerCallAction *)action
|
|
{
|
|
CallKitCall *call = [_calls objectForKey:action.callUUID];
|
|
if (call) {
|
|
call.isRinging = NO;
|
|
[self stopCallStateTimerForCallUUID:call.uuid];
|
|
|
|
[self stopHangUpTimerForCallUUID:call.uuid];
|
|
NSMutableDictionary *userInfo = [NSMutableDictionary dictionaryWithObject:call.token forKey:@"roomToken"];
|
|
[userInfo setValue:@(call.update.hasVideo) forKey:@"hasVideo"];
|
|
[userInfo setValue:@(call.reportedWhileInCall) forKey:@"waitForCallEnd"];
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:CallKitManagerDidAnswerCallNotification
|
|
object:self
|
|
userInfo:userInfo];
|
|
}
|
|
|
|
[action fulfill];
|
|
}
|
|
|
|
- (void)provider:(CXProvider *)provider performEndCallAction:(CXEndCallAction *)action
|
|
{
|
|
[action fulfill];
|
|
|
|
CallKitCall *call = [_calls objectForKey:action.callUUID];
|
|
if (call) {
|
|
call.isRinging = NO;
|
|
[self stopCallStateTimerForCallUUID:call.uuid];
|
|
|
|
[self stopHangUpTimerForCallUUID:call.uuid];
|
|
NSString *leaveCallToken = [call.token copy];
|
|
[_calls removeObjectForKey:action.callUUID];
|
|
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:leaveCallToken forKey:@"roomToken"];
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:CallKitManagerDidEndCallNotification
|
|
object:self
|
|
userInfo:userInfo];
|
|
}
|
|
}
|
|
|
|
- (void)provider:(CXProvider *)provider performSetMutedCallAction:(CXSetMutedCallAction *)action
|
|
{
|
|
CallKitCall *call = [_calls objectForKey:action.callUUID];
|
|
if (call) {
|
|
NSMutableDictionary *userInfo = [NSMutableDictionary dictionaryWithObject:call.token forKey:@"roomToken"];
|
|
[userInfo setValue:@(action.isMuted) forKey:@"isMuted"];
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:CallKitManagerDidChangeAudioMuteNotification
|
|
object:self
|
|
userInfo:userInfo];
|
|
}
|
|
|
|
[action fulfill];
|
|
}
|
|
|
|
- (void)provider:(CXProvider *)provider didActivateAudioSession:(AVAudioSession *)audioSession
|
|
{
|
|
NSLog(@"Provider:didActivateAudioSession - %@", audioSession);
|
|
[[NCAudioController sharedInstance] providerDidActivateAudioSession:audioSession];
|
|
}
|
|
|
|
- (void)provider:(CXProvider *)provider didDeactivateAudioSession:(nonnull AVAudioSession *)audioSession
|
|
{
|
|
NSLog(@"Provider:didDeactivateAudioSession - %@", audioSession);
|
|
[[NCAudioController sharedInstance] providerDidDeactivateAudioSession:audioSession];
|
|
}
|
|
|
|
|
|
@end
|