diff --git a/Classes/LinphoneAppDelegate.m b/Classes/LinphoneAppDelegate.m index 798060d5a..8f9d523d3 100644 --- a/Classes/LinphoneAppDelegate.m +++ b/Classes/LinphoneAppDelegate.m @@ -267,11 +267,7 @@ } - (void)processRemoteNotification:(NSDictionary*)userInfo{ - if ([LinphoneManager instance].pushNotificationToken==Nil){ - [LinphoneLogger log:LinphoneLoggerLog format:@"Ignoring push notification we did not subscribed."]; - return; - } - + NSDictionary *aps = [userInfo objectForKey:@"aps"]; if(aps != nil) { @@ -286,18 +282,22 @@ [LinphoneManager instance].connectivity=none; /*force connectivity to be discovered again*/ [[LinphoneManager instance] refreshRegisters]; if(loc_key != nil) { - if([loc_key isEqualToString:@"IM_MSG"]) { - [[PhoneMainView instance] addInhibitedEvent:kLinphoneTextReceived]; + + NSString* callId = [userInfo objectForKey:@"call-id"]; + if( callId != nil ){ + [[LinphoneManager instance] addPushCallId:callId]; + } else { + [LinphoneLogger log:LinphoneLoggerError format:@"PushNotification: does not have call-id yet, fix it !"]; + } + + if( [loc_key isEqualToString:@"IM_MSG"] ) { + [[PhoneMainView instance] changeCurrentView:[ChatViewController compositeViewDescription]]; - } else if([loc_key isEqualToString:@"IC_MSG"]) { - //it's a call - NSString *callid=[userInfo objectForKey:@"call-id"]; - if (callid) - [[LinphoneManager instance] enableAutoAnswerForCallId:callid]; - else - [LinphoneLogger log:LinphoneLoggerError format:@"PushNotification: does not have call-id yet, fix it !"]; + + } else if( [loc_key isEqualToString:@"IC_MSG"] ) { [self fixRing]; + } } } @@ -367,11 +367,6 @@ { Linphone_log(@"%@ : %@", NSStringFromSelector(_cmd), userInfo); LinphoneManager* lm = [LinphoneManager instance]; - - if (lm.pushNotificationToken==Nil){ - [LinphoneLogger log:LinphoneLoggerLog format:@"Ignoring push notification we did not subscribed."]; - return; - } // save the completion handler for later execution. // 2 outcomes: diff --git a/Classes/LinphoneManager.h b/Classes/LinphoneManager.h index f0545b9c6..99adcdb7d 100644 --- a/Classes/LinphoneManager.h +++ b/Classes/LinphoneManager.h @@ -107,7 +107,7 @@ typedef struct _LinphoneManagerSounds { @private NSTimer* mIterateTimer; - NSMutableArray* pendindCallIdFromRemoteNotif; + NSMutableArray* pushCallIDs; Connectivity connectivity; UIBackgroundTaskIdentifier pausedCallBgTask; UIBackgroundTaskIdentifier incallBgTask; @@ -137,9 +137,9 @@ typedef struct _LinphoneManagerSounds { - (BOOL)resignActive; - (void)becomeActive; - (BOOL)enterBackgroundMode; -- (void)enableAutoAnswerForCallId:(NSString*) callid; +- (void)addPushCallId:(NSString*) callid; - (void)configurePushTokenForProxyConfig: (LinphoneProxyConfig*)cfg; -- (BOOL)shouldAutoAcceptCallForCallId:(NSString*) callId; +- (BOOL)popPushCallID:(NSString*) callId; - (void)acceptCallForCallId:(NSString*)callid; - (void)cancelLocalNotifTimerForCallId:(NSString*)callid; diff --git a/Classes/LinphoneManager.m b/Classes/LinphoneManager.m index 4677b742e..3a08d0683 100644 --- a/Classes/LinphoneManager.m +++ b/Classes/LinphoneManager.m @@ -276,7 +276,7 @@ struct codec_name_pref_table codec_pref_table[]={ bluetoothEnabled = FALSE; tunnelMode = FALSE; [self copyDefaultSettings]; - pendindCallIdFromRemoteNotif = [[NSMutableArray alloc] init ]; + pushCallIDs = [[NSMutableArray alloc] init ]; photoLibrary = [[ALAssetsLibrary alloc] init]; NSString* factoryConfig = [LinphoneManager bundleFile:[LinphoneManager runningOnIpad]?@"linphonerc-factory~ipad":@"linphonerc-factory"]; @@ -311,7 +311,7 @@ struct codec_name_pref_table codec_pref_table[]={ [photoLibrary release]; - [pendindCallIdFromRemoteNotif release]; + [pushCallIDs release]; [super dealloc]; } @@ -663,7 +663,7 @@ static void linphone_iphone_display_status(struct _LinphoneCore * lc, const char LinphoneCallLog* callLog=linphone_call_get_call_log(call); NSString* callId=[NSString stringWithUTF8String:linphone_call_log_get_call_id(callLog)]; - if (![[LinphoneManager instance] shouldAutoAcceptCallForCallId:callId]){ + if (![[LinphoneManager instance] popPushCallID:callId]){ // case where a remote notification is not already received // Create a new local notification data->notification = [[UILocalNotification alloc] init]; @@ -878,14 +878,16 @@ static void linphone_iphone_registration_state(LinphoneCore *lc, LinphoneProxyCo silentPushCompletion(UIBackgroundFetchResultNewData); silentPushCompletion = nil; } + const LinphoneAddress* remoteAddress = linphone_chat_message_get_from_address(msg); + char* c_address = linphone_address_as_string_uri_only(remoteAddress); + NSString* address = [NSString stringWithUTF8String:c_address]; + const char* call_id = linphone_chat_message_get_custom_header(msg, "Call-ID"); + NSString* callID = [NSString stringWithUTF8String:call_id]; + + ms_free(c_address); if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground) { - const LinphoneAddress* remoteAddress = linphone_chat_message_get_from_address(msg); - char* c_address = linphone_address_as_string_uri_only(remoteAddress); - NSString* address = [NSString stringWithUTF8String:c_address]; - NSString* from_address = [address copy]; - ABRecordRef contact = [fastAddressBook getContact:address]; if(contact) { address = [FastAddressBook getContactDisplayName:contact]; @@ -910,18 +912,18 @@ static void linphone_iphone_registration_state(LinphoneCore *lc, LinphoneProxyCo notif.alertBody = [NSString stringWithFormat:NSLocalizedString(@"IM_MSG",nil), address]; notif.alertAction = NSLocalizedString(@"Show", nil); notif.soundName = @"msg.caf"; - notif.userInfo = @{@"from":from_address}; - + notif.userInfo = @{@"from":address, @"call-id":callID}; [[UIApplication sharedApplication] presentLocalNotificationNow:notif]; } - [from_address release]; } // Post event NSDictionary* dict = @{@"room" :[NSValue valueWithPointer:room], - @"from_address":[NSValue valueWithPointer:linphone_chat_message_get_from(msg)], - @"message" :[NSValue valueWithPointer:msg]}; + @"from_address":[NSValue valueWithPointer:linphone_chat_message_get_from_address(msg)], + @"message" :[NSValue valueWithPointer:msg], + @"call-id" : callID}; + [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneTextReceived object:self userInfo:dict]; } @@ -1532,23 +1534,23 @@ static int comp_call_id(const LinphoneCall* call , const char *callid) { }; } -- (void)enableAutoAnswerForCallId:(NSString*) callid { - //first, make sure this callid is not already involved in a call +- (void)addPushCallId:(NSString*) callid { + //first, make sure this callid is not already involved in a call MSList* calls = (MSList*)linphone_core_get_calls(theLinphoneCore); if (ms_list_find_custom(calls, (MSCompareFunc)comp_call_id, [callid UTF8String])) { - [LinphoneLogger log:LinphoneLoggerWarning format:@"Call id [%@] already handled",callid]; + Linphone_warn(@"Call id [%@] already handled",callid); return; }; - if ([pendindCallIdFromRemoteNotif count] > 10 /*max number of pending notif*/) - [pendindCallIdFromRemoteNotif removeObjectAtIndex:0]; + if ([pushCallIDs count] > 10 /*max number of pending notif*/) + [pushCallIDs removeObjectAtIndex:0]; - [pendindCallIdFromRemoteNotif addObject:callid]; + [pushCallIDs addObject:callid]; } -- (BOOL)shouldAutoAcceptCallForCallId:(NSString*) callId { - for (NSString* pendingNotif in pendindCallIdFromRemoteNotif) { +- (BOOL)popPushCallID:(NSString*) callId { + for (NSString* pendingNotif in pushCallIDs) { if ([pendingNotif compare:callId] == NSOrderedSame) { - [pendindCallIdFromRemoteNotif removeObject:pendingNotif]; + [pushCallIDs removeObject:pendingNotif]; return TRUE; } } diff --git a/Classes/PhoneMainView.m b/Classes/PhoneMainView.m index 7abadbd5e..2d220f2ad 100644 --- a/Classes/PhoneMainView.m +++ b/Classes/PhoneMainView.m @@ -270,10 +270,11 @@ static RootViewManager* rootViewManagerInstance = nil; #pragma mark - Event Functions - (void)textReceived:(NSNotification*)notif { - LinphoneAddress*from = [[notif.userInfo objectForKey:@"from_address"] pointerValue]; + LinphoneAddress* from = [[notif.userInfo objectForKey:@"from_address"] pointerValue]; + NSString* callID = [notif.userInfo objectForKey:@"call-id"]; if(from != nil) { - [self playMessageSound]; - } + [self playMessageSoundForCallID:callID]; + } [self updateApplicationBadgeNumber]; } @@ -653,22 +654,31 @@ static RootViewManager* rootViewManagerInstance = nil; #pragma mark - ActionSheet Functions -- (void)playMessageSound { +- (void)playMessageSoundForCallID:(NSString*)callID { if ([UIApplication sharedApplication].applicationState != UIApplicationStateBackground) { - if(![self removeInhibitedEvent:kLinphoneTextReceived]) { - [[LinphoneManager instance] playMessageSound]; + LinphoneManager* lm = [LinphoneManager instance]; + // if the message was already received through a push notif, we don't need to ring + if( ![lm popPushCallID:callID] ) { + [lm playMessageSound]; } } } - (void)displayIncomingCall:(LinphoneCall*) call{ - LinphoneCallLog* callLog=linphone_call_get_call_log(call); - NSString* callId=[NSString stringWithUTF8String:linphone_call_log_get_call_id(callLog)]; + LinphoneCallLog* callLog = linphone_call_get_call_log(call); + NSString* callId = [NSString stringWithUTF8String:linphone_call_log_get_call_id(callLog)]; if ([UIApplication sharedApplication].applicationState != UIApplicationStateBackground) { - if ([[LinphoneManager instance] shouldAutoAcceptCallForCallId:callId]){ - [[LinphoneManager instance] acceptCall:call]; - }else { + LinphoneManager* lm = [LinphoneManager instance]; + BOOL callIDFromPush = [lm popPushCallID:callId]; + BOOL autoAnswer = [lm lpConfigBoolForKey:@"autoanswer_notif_preference"]; + + if (callIDFromPush && autoAnswer){ + // accept call automatically + [lm acceptCall:call]; + + } else { + IncomingCallViewController *controller = nil; if( ![currentView.name isEqualToString:[IncomingCallViewController compositeViewDescription].name]){ controller = DYNAMIC_CAST([self changeCurrentView:[IncomingCallViewController compositeViewDescription] push:TRUE],IncomingCallViewController); @@ -676,11 +686,12 @@ static RootViewManager* rootViewManagerInstance = nil; // controller is already presented, don't bother animating a transition controller = DYNAMIC_CAST([self.mainViewController getCurrentViewController],IncomingCallViewController); } - AudioServicesPlaySystemSound([LinphoneManager instance].sounds.vibrate); + AudioServicesPlaySystemSound(lm.sounds.vibrate); if(controller != nil) { [controller setCall:call]; [controller setDelegate:self]; } + } } }