fix display imcoming call repeatedly

This commit is contained in:
Danmei Chen 2020-03-05 16:21:41 +01:00
parent b6fe76753e
commit e7ed8d60bb
5 changed files with 74 additions and 14 deletions

View file

@ -113,6 +113,15 @@ import AVFoundation
return false
}
@objc static func incomingCallMustBeDisplayed() -> Bool {
if #available(iOS 13.0, *) {
if UIApplication.shared.applicationState == .background && CallManager.callKitEnabled() {
return true
}
}
return false
}
@objc func allowSpeaker() -> Bool {
if (UIDevice.current.userInterfaceIdiom == .pad) {
// For now, ipad support only speaker.
@ -161,6 +170,15 @@ import AVFoundation
displayIncomingCall(call: nil, handle: "Calling", hasVideo: false, callId: callId)
}
// There is an error before display an incoming call. Attention, it's unnormal in this case!
@objc func displayForkIncomingCall() {
if CallManager.incomingCallMustBeDisplayed() {
// Display the call in any way, otherwise it will cause a crash.
Log.directLog(BCTBX_LOG_ERROR, text: "CallKit: please check the pushkit notification, there must be something wrong!")
providerDelegate.reportForkIncomingCall();
}
}
func displayIncomingCall(call:Call?, handle: String, hasVideo: Bool, callId: String) {
let uuid = UUID()
let callInfo = CallInfo.newIncomingCallInfo(callId: callId)

View file

@ -36,6 +36,7 @@
- (void)registerForNotifications;
@property (atomic, strong) NSString *callIdTraitedInBackGround;
@property (nonatomic, retain) UIAlertController *waitingIndicator;
@property (nonatomic, retain) NSString *configURL;
@property (nonatomic, strong) UIWindow* window;

View file

@ -46,6 +46,7 @@
self = [super init];
if (self != nil) {
startedInBackground = FALSE;
_callIdTraitedInBackGround = @"";
}
_alreadyRegisteredForNotification = false;
_onlyPortrait = FALSE;
@ -58,6 +59,7 @@
- (void)applicationDidEnterBackground:(UIApplication *)application {
LOGI(@"%@", NSStringFromSelector(_cmd));
[LinphoneManager.instance enterBackgroundMode];
_callIdTraitedInBackGround = @"";
}
- (void)applicationWillResignActive:(UIApplication *)application {
@ -427,33 +429,58 @@
}
}
- (void)processRemoteNotification:(NSDictionary *)userInfo {
if (linphone_core_get_calls(LC)) {
// if there are calls, obviously our TCP socket shall be working
LOGD(@"Notification [%p] has no need to be processed because there already is an active call.", userInfo);
return;
}
-(void)displayfailedcall {
}
- (void)processRemoteNotification:(NSDictionary *)userInfo {
// TODO: it works only for calls.
NSDictionary *aps = [userInfo objectForKey:@"aps"];
if (!aps) {
LOGE(@"Notification [%p] was empy, it's impossible to process it.", userInfo);
[CallManager.instance displayForkIncomingCall];
return;
}
NSString *loc_key = [aps objectForKey:@"loc-key"] ?: [[aps objectForKey:@"alert"] objectForKey:@"loc-key"];
if (!loc_key) {
LOGE(@"Notification [%p] has no loc_key, it's impossible to process it.", userInfo);
[CallManager.instance displayForkIncomingCall];
return;
}
NSString *callId = [aps objectForKey:@"call-id"] ?: @"";
if (![callId isEqualToString:@""] && [loc_key isEqualToString:@"IC_MSG"] && [CallManager callKitEnabled]) {
// Report a new Incoming call without lantacy when the callkit is enabled.
if ([UIApplication sharedApplication].applicationState != UIApplicationStateActive && [self addLongTaskIDforCallID:callId]) {
[LinphoneManager.instance startPushLongRunningTask:loc_key callId:callId];
if ([callId isEqualToString:@""]) {
[CallManager.instance displayForkIncomingCall];
}
if (![loc_key isEqualToString:@"IC_MSG"]) {
[CallManager.instance displayForkIncomingCall];
}
if([CallManager incomingCallMustBeDisplayed]) {
// Since ios13, a new Incoming call must be displayed when the callkit is enabled and app is in background.
// Otherwise it will cause a crash.
if ([_callIdTraitedInBackGround isEqualToString:callId]) {
LOGD(@"Notification has traited (Background).");
} else {
_callIdTraitedInBackGround = callId;
if ([UIApplication sharedApplication].applicationState != UIApplicationStateActive && [self addLongTaskIDforCallID:callId]) {
[LinphoneManager.instance startPushLongRunningTask:loc_key callId:callId];
}
[LinphoneManager.instance addPushCallId:callId];
[CallManager.instance displayIncomingCallWithCallId:callId];
}
} else {
if (linphone_core_get_calls(LC)) {
// if there are calls, obviously our TCP socket shall be working
LOGD(@"Notification [%p] has no need to be processed because there already is an active call.", userInfo);
return;
}
if ([_callIdTraitedInBackGround isEqualToString:callId]) {
LOGD(@"Notification has traited (Foreground).");
return;
}
[LinphoneManager.instance addPushCallId:callId];
} else {
NSString *uuid = [NSString stringWithFormat:@"<urn:uuid:%@>", [LinphoneManager.instance lpConfigStringForKey:@"uuid" inSection:@"misc" withDefault:NULL]];
NSString *sipInstance = [aps objectForKey:@"uuid"];
if (sipInstance && uuid && ![sipInstance isEqualToString:uuid]) {
@ -487,6 +514,12 @@
notification.alertTitle = @"APN Pusher";
[[UIApplication sharedApplication] presentLocalNotificationNow:notification];
}
} else if (![callId isEqualToString:@""] && [loc_key isEqualToString:@"IC_MSG"] && [CallManager callKitEnabled]) {
// Report a new Incoming call when app is in foreground.
if ([UIApplication sharedApplication].applicationState != UIApplicationStateActive && [self addLongTaskIDforCallID:callId]) {
[LinphoneManager.instance startPushLongRunningTask:loc_key callId:callId];
}
[LinphoneManager.instance addPushCallId:callId];
}
}

View file

@ -1558,7 +1558,6 @@ static int comp_call_id(const LinphoneCall *call, const char *callid) {
[pushCallIDs removeObjectAtIndex:0];
[pushCallIDs addObject:callid];
[CallManager.instance displayIncomingCallWithCallId:callid];
}
- (BOOL)popPushCallID:(NSString *)callId {

View file

@ -104,6 +104,15 @@ class ProviderDelegate: NSObject {
}
}
}
func reportForkIncomingCall() {
let uuid = UUID()
let update = CXCallUpdate()
update.remoteHandle = CXHandle(type:.generic, value: "Unknow")
provider.reportNewIncomingCall(with: uuid, update: update, completion: {_ in})
provider.reportCall(with: uuid, endedAt: .init(), reason: .failed)
}
func updateCall(uuid: UUID, handle: String, hasVideo: Bool = false) {
let update = CXCallUpdate()