diff --git a/.gitignore b/.gitignore index 3e162d2d6..20dcb5af7 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ git-clang-format.diff submodules/tunnel submodules/binaries/dummy-*.a linphone-iphone.ipa +TutorialHellowWorld/hello-world.xcodeproj/project.xcworkspace/ diff --git a/.gitmodules b/.gitmodules index d29905eee..d1862f96a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,57 +1,57 @@ [submodule "submodules/linphone"] path = submodules/linphone - url = git://git.linphone.org/linphone + url = git://git.linphone.org/linphone.git [submodule "submodules/externals/gsm"] path = submodules/externals/gsm - url = git://git.linphone.org/gsm + url = git://git.linphone.org/gsm.git [submodule "submodules/externals/speex"] path = submodules/externals/speex - url = git://git.linphone.org/speex + url = git://git.linphone.org/speex.git [submodule "submodules/externals/opencore-amr"] path = submodules/externals/opencore-amr url = git://git.linphone.org/opencore-amr.git ignore = dirty [submodule "submodules/msamr"] path = submodules/msamr - url = git://git.linphone.org/msamr + url = git://git.linphone.org/msamr.git [submodule "submodules/externals/ffmpeg"] path = submodules/externals/ffmpeg - url = git://git.linphone.org/ffmpeg + url = git://git.linphone.org/ffmpeg.git [submodule "submodules/externals/x264"] path = submodules/externals/x264 - url = git://git.linphone.org/x264 + url = git://git.linphone.org/x264.git ignore = dirty [submodule "submodules/msx264"] path = submodules/msx264 - url = git://git.linphone.org/msx264 + url = git://git.linphone.org/msx264.git [submodule "submodules/externals/libvpx"] path = submodules/externals/libvpx - url = git://git.linphone.org/libvpx + url = git://git.linphone.org/libvpx.git ignore = dirty [submodule "submodules/bzrtp"] path = submodules/bzrtp - url = git://git.linphone.org/bzrtp + url = git://git.linphone.org/bzrtp.git [submodule "submodules/mssilk"] path = submodules/mssilk - url = git://git.linphone.org/mssilk + url = git://git.linphone.org/mssilk.git [submodule "submodules/externals/srtp"] path = submodules/externals/srtp - url = git://git.linphone.org/srtp + url = git://git.linphone.org/srtp.git [submodule "submodules/bcg729"] path = submodules/bcg729 - url = git://git.linphone.org/bcg729 + url = git://git.linphone.org/bcg729.git [submodule "submodules/belle-sip"] path = submodules/belle-sip - url = git://git.linphone.org/belle-sip + url = git://git.linphone.org/belle-sip.git [submodule "submodules/externals/antlr3"] path = submodules/externals/antlr3 - url = git://git.linphone.org/antlr3 + url = git://git.linphone.org/antlr3.git [submodule "submodules/externals/polarssl"] path = submodules/externals/polarssl - url = git://git.linphone.org/polarssl + url = git://git.linphone.org/polarssl.git [submodule "submodules/externals/opus"] path = submodules/externals/opus - url = git://git.linphone.org/opus + url = git://git.linphone.org/opus.git ignore = dirty [submodule "submodules/externals/libxml2"] path = submodules/externals/libxml2 @@ -59,7 +59,7 @@ ignore = dirty [submodule "submodules/cunit"] path = submodules/cunit - url = git://git.linphone.org/cunit + url = git://git.linphone.org/cunit.git ignore = dirty [submodule "submodules/externals/openh264"] path = submodules/externals/openh264 @@ -67,21 +67,24 @@ ignore = dirty [submodule "submodules/msopenh264"] path = submodules/msopenh264 - url = git://git.linphone.org/msopenh264 + url = git://git.linphone.org/msopenh264.git [submodule "submodules/mswebrtc"] path = submodules/mswebrtc - url = git://git.linphone.org/mswebrtc + url = git://git.linphone.org/mswebrtc.git [submodule "Classes/KIF"] path = Classes/KIF url = https://github.com/kif-framework/KIF ignore = dirty [submodule "submodules/cmake-builder"] path = submodules/cmake-builder - url = git://git.linphone.org/linphone-cmake-builder + url = git://git.linphone.org/linphone-cmake-builder.git [submodule "submodules/externals/vo-amrwbenc"] path = submodules/externals/vo-amrwbenc - url = git://git.linphone.org/vo-amrwbenc + url = git://git.linphone.org/vo-amrwbenc.git ignore = dirty +[submodule "submodules/externals/libmatroska-c"] + path = submodules/externals/libmatroska-c + url = git://git.linphone.org/libmatroska-c.git [submodule "submodules/belr"] path = submodules/belr url = git://git.linphone.org/belr diff --git a/.travis.yml b/.travis.yml index 8970b7494..f63d2e09a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,5 @@ language: objective-c +osx_image: xcode7.2 env: global: @@ -7,8 +8,7 @@ env: before_install: - brew update 1>/dev/null - - brew install doxygen nasm yasm optipng imagemagick coreutils intltool ninja antlr - - brew upgrade cmake + - brew install doxygen nasm yasm optipng imagemagick intltool ninja antlr cmake - wget --no-check-certificate https://raw.githubusercontent.com/FFmpeg/gas-preprocessor/master/gas-preprocessor.pl - chmod +x gas-preprocessor.pl - sudo mv gas-preprocessor.pl /usr/local/bin diff --git a/Classes/AssistantView.m b/Classes/AssistantView.m index 89317afc5..daa9e9877 100644 --- a/Classes/AssistantView.m +++ b/Classes/AssistantView.m @@ -147,19 +147,6 @@ static UICompositeViewDescription *compositeDescription = nil; - (void)reset { [LinphoneManager.instance removeAllAccounts]; - [LinphoneManager.instance lpConfigSetBool:FALSE forKey:@"pushnotification_preference"]; - - LinphoneCore *lc = LC; - LCSipTransports transportValue = {5060, 5060, -1, -1}; - - if (linphone_core_set_sip_transports(lc, &transportValue)) { - LOGE(@"cannot set transport"); - } - - [LinphoneManager.instance lpConfigSetBool:FALSE forKey:@"ice_preference"]; - [LinphoneManager.instance lpConfigSetString:@"" forKey:@"stun_preference"]; - linphone_core_set_stun_server(lc, NULL); - linphone_core_set_firewall_policy(lc, LinphonePolicyNoFirewall); [self resetTextFields]; [self changeView:_welcomeView back:FALSE animation:FALSE]; _waitView.hidden = TRUE; @@ -213,15 +200,28 @@ static UICompositeViewDescription *compositeDescription = nil; } - (void)configureProxyConfig { - LinphoneCore *lc = LC; LinphoneManager *lm = LinphoneManager.instance; + if (!linphone_core_is_network_reachable(LC)) { + UIAlertView *error = + [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Network Error", nil) + message:NSLocalizedString(@"There is no network connection available, enable " + @"WIFI or WWAN prior to configure an account", + nil) + delegate:nil + cancelButtonTitle:NSLocalizedString(@"Cancel", nil) + otherButtonTitles:nil]; + [error show]; + _waitView.hidden = YES; + return; + } + // remove previous proxy config, if any if (new_config != NULL) { const LinphoneAuthInfo *auth = linphone_proxy_config_find_auth_info(new_config); - linphone_core_remove_proxy_config(lc, new_config); + linphone_core_remove_proxy_config(LC, new_config); if (auth) { - linphone_core_remove_auth_info(lc, auth); + linphone_core_remove_auth_info(LC, auth); } } @@ -229,7 +229,7 @@ static UICompositeViewDescription *compositeDescription = nil; if (new_config) { [lm configurePushTokenForProxyConfig:new_config]; - linphone_core_set_default_proxy_config(lc, new_config); + linphone_core_set_default_proxy_config(LC, new_config); // reload address book to prepend proxy config domain to contacts' phone number // todo: STOP doing that! [[LinphoneManager.instance fastAddressBook] reload]; diff --git a/Classes/Base.lproj/AssistantView.xib b/Classes/Base.lproj/AssistantView.xib index 085bef1d5..0d71cc256 100644 --- a/Classes/Base.lproj/AssistantView.xib +++ b/Classes/Base.lproj/AssistantView.xib @@ -1,5 +1,5 @@ - + @@ -67,7 +67,7 @@ - + diff --git a/Classes/Base.lproj/AssistantViewScreens.strings b/Classes/Base.lproj/AssistantViewScreens.strings index aa3369656..04601633e 100644 Binary files a/Classes/Base.lproj/AssistantViewScreens.strings and b/Classes/Base.lproj/AssistantViewScreens.strings differ diff --git a/Classes/Base.lproj/AssistantViewScreens.xib b/Classes/Base.lproj/AssistantViewScreens.xib index 60e88fe56..42b5e62eb 100644 --- a/Classes/Base.lproj/AssistantViewScreens.xib +++ b/Classes/Base.lproj/AssistantViewScreens.xib @@ -1,5 +1,5 @@ - + @@ -22,11 +22,11 @@ - + - + - + - + - + @@ -157,21 +157,21 @@ - + @@ -184,21 +184,21 @@ - + @@ -211,21 +211,21 @@ - + @@ -238,14 +238,14 @@ - + @@ -161,6 +164,9 @@ - + @@ -285,7 +291,7 @@ - + diff --git a/Classes/Base.lproj/CallOutgoingView.xib b/Classes/Base.lproj/CallOutgoingView.xib index 6d3ac0234..62e9b7ff6 100644 --- a/Classes/Base.lproj/CallOutgoingView.xib +++ b/Classes/Base.lproj/CallOutgoingView.xib @@ -34,6 +34,9 @@ - + @@ -218,6 +221,9 @@ - + @@ -382,7 +388,7 @@ - + diff --git a/Classes/Base.lproj/CallView.xib b/Classes/Base.lproj/CallView.xib index 8eda3cad7..f2bc14676 100644 --- a/Classes/Base.lproj/CallView.xib +++ b/Classes/Base.lproj/CallView.xib @@ -195,11 +195,11 @@ - + @@ -628,34 +598,6 @@ - - @@ -691,14 +633,10 @@ - - - - diff --git a/Classes/CallConferenceTableView.h b/Classes/CallConferenceTableView.h index d7d8b201f..9034a155e 100644 --- a/Classes/CallConferenceTableView.h +++ b/Classes/CallConferenceTableView.h @@ -8,9 +8,8 @@ #import -@interface CallConferenceTableView : UITableViewController { - @private - NSTimer *updateTime; -} +@interface CallConferenceTableView : UITableViewController + +- (void)update; @end diff --git a/Classes/CallConferenceTableView.m b/Classes/CallConferenceTableView.m index 71bd14208..cfbffb279 100644 --- a/Classes/CallConferenceTableView.m +++ b/Classes/CallConferenceTableView.m @@ -24,22 +24,6 @@ @implementation CallConferenceTableView -#pragma mark - ViewController Functions - -- (void)viewWillAppear:(BOOL)animated { - [super viewWillAppear:animated]; - updateTime = - [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(update) userInfo:nil repeats:YES]; -} - -- (void)viewWillDisappear:(BOOL)animated { - [super viewWillDisappear:animated]; - if (updateTime != nil) { - [updateTime invalidate]; - updateTime = nil; - } -} - #pragma mark - UI change - (void)update { diff --git a/Classes/CallIncomingView.m b/Classes/CallIncomingView.m index 6d8d29b8d..b73f4ff28 100644 --- a/Classes/CallIncomingView.m +++ b/Classes/CallIncomingView.m @@ -38,8 +38,8 @@ - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; - [NSNotificationCenter.defaultCenter removeObserver:self name:kLinphoneCallUpdate object:nil]; + _call = NULL; } #pragma mark - UICompositeViewDelegate Functions @@ -64,6 +64,13 @@ static UICompositeViewDescription *compositeDescription = nil; return self.class.compositeViewDescription; } +- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { + [super didRotateFromInterfaceOrientation:fromInterfaceOrientation]; + if (_call) { + [self update]; + } +} + #pragma mark - Event Functions - (void)callUpdateEvent:(NSNotification *)notif { @@ -75,7 +82,6 @@ static UICompositeViewDescription *compositeDescription = nil; - (void)callUpdate:(LinphoneCall *)acall state:(LinphoneCallState)astate { if (_call == acall && (astate == LinphoneCallEnd || astate == LinphoneCallError)) { [_delegate incomingCallAborted:_call]; - [self dismiss]; } else if ([LinphoneManager.instance lpConfigBoolForKey:@"auto_answer"]) { LinphoneCallState state = linphone_call_get_state(_call); if (state == LinphoneCallIncomingReceived) { @@ -87,12 +93,6 @@ static UICompositeViewDescription *compositeDescription = nil; #pragma mark - -- (void)dismiss { - if ([[PhoneMainView.instance currentView] equal:CallIncomingView.compositeViewDescription]) { - [PhoneMainView.instance popCurrentView]; - } -} - - (void)update { const LinphoneAddress *addr = linphone_call_get_remote_address(_call); [ContactDisplay setDisplayNameLabel:_nameLabel forAddress:addr]; @@ -116,17 +116,14 @@ static UICompositeViewDescription *compositeDescription = nil; #pragma mark - Action Functions - (IBAction)onAcceptClick:(id)event { - [self dismiss]; [_delegate incomingCallAccepted:_call evenWithVideo:YES]; } - (IBAction)onDeclineClick:(id)event { - [self dismiss]; [_delegate incomingCallDeclined:_call]; } - (IBAction)onAcceptAudioOnlyClick:(id)sender { - [self dismiss]; [_delegate incomingCallAccepted:_call evenWithVideo:NO]; } diff --git a/Classes/CallOutgoingView.m b/Classes/CallOutgoingView.m index 43ee7fb7e..7bcf73938 100644 --- a/Classes/CallOutgoingView.m +++ b/Classes/CallOutgoingView.m @@ -45,6 +45,10 @@ static UICompositeViewDescription *compositeDescription = nil; return self.class.compositeViewDescription; } +- (void)viewDidLoad { + _routesEarpieceButton.enabled = !IPAD; +} + - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; @@ -109,9 +113,6 @@ static UICompositeViewDescription *compositeDescription = nil; } - (void)hideRoutes:(BOOL)hidden animated:(BOOL)animated { - if (IPAD) - return; - if (hidden) { [_routesButton setOff]; } else { @@ -128,8 +129,6 @@ static UICompositeViewDescription *compositeDescription = nil; } - (void)hideSpeaker:(BOOL)hidden { - if (IPAD) - return; _speakerButton.hidden = hidden; _routesButton.hidden = !hidden; } diff --git a/Classes/CallPausedTableView.h b/Classes/CallPausedTableView.h index 7b64bc45e..0fe820402 100644 --- a/Classes/CallPausedTableView.h +++ b/Classes/CallPausedTableView.h @@ -19,9 +19,8 @@ #import -@interface CallPausedTableView : UITableViewController { - @private - NSTimer *updateTime; -} +@interface CallPausedTableView : UITableViewController + +- (void)update; @end diff --git a/Classes/CallPausedTableView.m b/Classes/CallPausedTableView.m index 5878d3588..8a3dc4256 100644 --- a/Classes/CallPausedTableView.m +++ b/Classes/CallPausedTableView.m @@ -24,22 +24,6 @@ @implementation CallPausedTableView -#pragma mark - ViewController Functions - -- (void)viewWillAppear:(BOOL)animated { - [super viewWillAppear:animated]; - updateTime = - [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(update) userInfo:nil repeats:YES]; -} - -- (void)viewWillDisappear:(BOOL)animated { - [super viewWillDisappear:animated]; - if (updateTime != nil) { - [updateTime invalidate]; - updateTime = nil; - } -} - #pragma mark - UI change - (void)update { diff --git a/Classes/CallSideMenuView.m b/Classes/CallSideMenuView.m index e53fa3ffb..60b34379c 100644 --- a/Classes/CallSideMenuView.m +++ b/Classes/CallSideMenuView.m @@ -143,6 +143,12 @@ NSMutableString *stats = [[NSMutableString alloc] init]; + LinphoneMediaEncryption enc = linphone_call_params_get_media_encryption(linphone_call_get_current_params(call)); + if (enc != LinphoneMediaEncryptionNone) { + [stats appendString:[NSString + stringWithFormat:@"Call encrypted using %s", linphone_media_encryption_to_string(enc)]]; + } + [stats appendString:[self updateStatsForCall:call stream:LinphoneStreamTypeAudio]]; [stats appendString:[self updateStatsForCall:call stream:LinphoneStreamTypeVideo]]; [stats appendString:[self updateStatsForCall:call stream:LinphoneStreamTypeText]]; diff --git a/Classes/CallView.m b/Classes/CallView.m index 64394e1ab..e8aa0294a 100644 --- a/Classes/CallView.m +++ b/Classes/CallView.m @@ -77,9 +77,14 @@ static UICompositeViewDescription *compositeDescription = nil; - (void)viewDidLoad { [super viewDidLoad]; + _routesEarpieceButton.enabled = !IPAD; + +// TODO: fixme! video preview frame is too big compared to openGL preview +// frame, so until this is fixed, temporary disabled it. +#if 0 _videoPreview.layer.borderColor = UIColor.whiteColor.CGColor; _videoPreview.layer.borderWidth = 1; - +#endif [singleFingerTap setNumberOfTapsRequired:1]; [singleFingerTap setCancelsTouchesInView:FALSE]; [self.videoView addGestureRecognizer:singleFingerTap]; @@ -131,12 +136,11 @@ static UICompositeViewDescription *compositeDescription = nil; - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; + LinphoneManager.instance.nextCallIsTransfer = NO; + [self updateUnreadMessage:FALSE]; // Update on show - LinphoneCall *call = linphone_core_get_current_call(LC); - LinphoneCallState state = (call != NULL) ? linphone_call_get_state(call) : 0; - [self callUpdate:call state:state animated:FALSE]; [self hideRoutes:TRUE animated:FALSE]; [self hideOptions:TRUE animated:FALSE]; [self hidePad:TRUE animated:FALSE]; @@ -180,6 +184,11 @@ static UICompositeViewDescription *compositeDescription = nil; [PhoneMainView.instance setVolumeHidden:TRUE]; hiddenVolume = TRUE; + + // we must wait didAppear to reset fullscreen mode because we cannot change it in viewwillappear + LinphoneCall *call = linphone_core_get_current_call(LC); + LinphoneCallState state = (call != NULL) ? linphone_call_get_state(call) : 0; + [self callUpdate:call state:state animated:FALSE]; } - (void)viewWillDisappear:(BOOL)animated { @@ -242,8 +251,6 @@ static void hideSpinner(LinphoneCall *call, void *user_data) { } - (void)updateBottomBar:(LinphoneCall *)call state:(LinphoneCallState)state { - LinphoneCore *lc = LC; - [_speakerButton update]; [_microButton update]; [_callPauseButton update]; @@ -254,9 +261,9 @@ static void hideSpinner(LinphoneCall *call, void *user_data) { _optionsButton.enabled = (!call || !linphone_call_media_in_progress(call)); _optionsTransferButton.enabled = call && !linphone_call_media_in_progress(call); // Show Pause/Conference button following call count - if (linphone_core_get_calls_nb(lc) > 1) { - bool enabled = ((linphone_core_get_current_call(lc) != NULL) || linphone_core_is_in_conference(lc)); - const MSList *list = linphone_core_get_calls(lc); + if (linphone_core_get_calls_nb(LC) > 1) { + bool enabled = ((linphone_core_get_current_call(LC) != NULL) || linphone_core_is_in_conference(LC)); + const MSList *list = linphone_core_get_calls(LC); while (list != NULL) { LinphoneCall *call = (LinphoneCall *)list->data; LinphoneCallState state = linphone_call_get_state(call); @@ -273,7 +280,7 @@ static void hideSpinner(LinphoneCall *call, void *user_data) { } // Disable transfert in conference - if (linphone_core_get_current_call(lc) == NULL) { + if (linphone_core_get_current_call(LC) == NULL) { [_optionsTransferButton setEnabled:FALSE]; } else { [_optionsTransferButton setEnabled:TRUE]; @@ -393,7 +400,7 @@ static void hideSpinner(LinphoneCall *call, void *user_data) { [self disableVideoDisplay:FALSE animated:animated]; } -- (void)displayTableCall:(BOOL)animated { +- (void)displayAudioCall:(BOOL)animated { [self disableVideoDisplay:TRUE animated:animated]; } @@ -408,16 +415,18 @@ static void hideSpinner(LinphoneCall *call, void *user_data) { int duration = linphone_core_get_current_call(LC) ? linphone_call_get_duration(linphone_core_get_current_call(LC)) : 0; _durationLabel.text = [LinphoneUtils durationToString:duration]; + + [_pausedCallsTable update]; + [_conferenceCallsTable update]; } - (void)onCurrentCallChange { - LinphoneCore *lc = LC; - LinphoneCall *call = linphone_core_get_current_call(lc); + LinphoneCall *call = linphone_core_get_current_call(LC); - _noActiveCallView.hidden = (call || linphone_core_is_in_conference(lc)); + _noActiveCallView.hidden = (call || linphone_core_is_in_conference(LC)); _callView.hidden = !call; - _conferenceView.hidden = !linphone_core_is_in_conference(lc); - _callPauseButton.hidden = !call && !linphone_core_is_in_conference(lc); + _conferenceView.hidden = !linphone_core_is_in_conference(LC); + _callPauseButton.hidden = !call && !linphone_core_is_in_conference(LC); [_callPauseButton setType:UIPauseButtonType_CurrentCall call:call]; [_conferencePauseButton setType:UIPauseButtonType_Conference call:call]; @@ -447,9 +456,6 @@ static void hideSpinner(LinphoneCall *call, void *user_data) { } - (void)hideRoutes:(BOOL)hidden animated:(BOOL)animated { - if (IPAD) - return; - if (hidden) { [_routesButton setOff]; } else { @@ -485,8 +491,6 @@ static void hideSpinner(LinphoneCall *call, void *user_data) { } - (void)hideSpeaker:(BOOL)hidden { - if (IPAD) - return; _speakerButton.hidden = hidden; _routesButton.hidden = !hidden; } @@ -505,7 +509,6 @@ static void hideSpinner(LinphoneCall *call, void *user_data) { } - (void)callUpdate:(LinphoneCall *)call state:(LinphoneCallState)state animated:(BOOL)animated { - LinphoneCore *lc = LC; [self updateBottomBar:call state:state]; if (hiddenVolume) { [PhoneMainView.instance setVolumeHidden:FALSE]; @@ -513,12 +516,12 @@ static void hideSpinner(LinphoneCall *call, void *user_data) { } // Update tables - [_pausedCallsTable.tableView reloadData]; - [_conferenceCallsTable.tableView reloadData]; + [_pausedCallsTable update]; + [_conferenceCallsTable update]; static LinphoneCall *currentCall = NULL; - if (!currentCall || linphone_core_get_current_call(lc) != currentCall) { - currentCall = linphone_core_get_current_call(lc); + if (!currentCall || linphone_core_get_current_call(LC) != currentCall) { + currentCall = linphone_core_get_current_call(LC); [self onCurrentCallChange]; } @@ -527,6 +530,16 @@ static void hideSpinner(LinphoneCall *call, void *user_data) { return; } + BOOL shouldDisableVideo = + (!currentCall || !linphone_call_params_video_enabled(linphone_call_get_current_params(currentCall))); + if (videoHidden != shouldDisableVideo) { + if (!shouldDisableVideo) { + [self displayVideoCall:animated]; + } else { + [self displayAudioCall:animated]; + } + } + if (state != LinphoneCallPausedByRemote) { _pausedByRemoteView.hidden = YES; } @@ -537,10 +550,7 @@ static void hideSpinner(LinphoneCall *call, void *user_data) { case LinphoneCallConnected: case LinphoneCallStreamsRunning: { // check video - if (linphone_call_params_video_enabled(linphone_call_get_current_params(call))) { - [self displayVideoCall:animated]; - } else { - [self displayTableCall:animated]; + if (!linphone_call_params_video_enabled(linphone_call_get_current_params(call))) { const LinphoneCallParams *param = linphone_call_get_current_params(call); const LinphoneCallAppData *callAppData = (__bridge const LinphoneCallAppData *)(linphone_call_get_user_pointer(call)); @@ -566,22 +576,23 @@ static void hideSpinner(LinphoneCall *call, void *user_data) { const LinphoneCallParams *remote = linphone_call_get_remote_params(call); /* remote wants to add video */ - if (linphone_core_video_display_enabled(lc) && !linphone_call_params_video_enabled(current) && + if (linphone_core_video_display_enabled(LC) && !linphone_call_params_video_enabled(current) && linphone_call_params_video_enabled(remote) && - !linphone_core_get_video_policy(lc)->automatically_accept) { - linphone_core_defer_call_update(lc, call); + !linphone_core_get_video_policy(LC)->automatically_accept) { + linphone_core_defer_call_update(LC, call); [self displayAskToEnableVideoCall:call]; } else if (linphone_call_params_video_enabled(current) && !linphone_call_params_video_enabled(remote)) { - [self displayTableCall:animated]; + [self displayAudioCall:animated]; } break; } case LinphoneCallPausing: case LinphoneCallPaused: - [self displayTableCall:animated]; + [self displayAudioCall:animated]; break; case LinphoneCallPausedByRemote: - if (call == linphone_core_get_current_call(lc)) { + [self displayAudioCall:animated]; + if (call == linphone_core_get_current_call(LC)) { _pausedByRemoteView.hidden = NO; } break; @@ -664,7 +675,7 @@ static void hideSpinner(LinphoneCall *call, void *user_data) { dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [UIView animateWithDuration:0.3 animations:^{ - LOGI(@"Recentering preview to %@", NSStringFromCGRect(previewFrame)); + LOGD(@"Recentering preview to %@", NSStringFromCGRect(previewFrame)); _videoPreview.frame = previewFrame; }]; }); @@ -713,7 +724,7 @@ static void hideSpinner(LinphoneCall *call, void *user_data) { [self hideOptions:TRUE animated:TRUE]; DialerView *view = VIEW(DialerView); [view setAddress:@""]; - [view setTransferMode:TRUE]; + LinphoneManager.instance.nextCallIsTransfer = YES; [PhoneMainView.instance changeCurrentView:view.compositeViewDescription]; } @@ -721,7 +732,7 @@ static void hideSpinner(LinphoneCall *call, void *user_data) { [self hideOptions:TRUE animated:TRUE]; DialerView *view = VIEW(DialerView); [view setAddress:@""]; - [view setTransferMode:FALSE]; + LinphoneManager.instance.nextCallIsTransfer = NO; [PhoneMainView.instance changeCurrentView:view.compositeViewDescription]; } diff --git a/Classes/ChatConversationCreateTableView.m b/Classes/ChatConversationCreateTableView.m index 0e069f238..8cd997891 100644 --- a/Classes/ChatConversationCreateTableView.m +++ b/Classes/ChatConversationCreateTableView.m @@ -45,7 +45,7 @@ }]; // also add current entry, if not listed NSString *nsuri = filter.lowercaseString; - LinphoneAddress *addr = linphone_core_interpret_url(LC, nsuri.UTF8String); + LinphoneAddress *addr = linphone_address_new(nsuri.UTF8String); if (addr) { char *uri = linphone_address_as_string(addr); nsuri = [NSString stringWithUTF8String:uri]; diff --git a/Classes/ChatConversationTableView.m b/Classes/ChatConversationTableView.m index 286df380d..e26d24f6d 100644 --- a/Classes/ChatConversationTableView.m +++ b/Classes/ChatConversationTableView.m @@ -41,10 +41,7 @@ #pragma mark - - (void)clearMessageList { - if (messageList) { - ms_list_free_with_data(messageList, (void (*)(void *))linphone_chat_message_unref); - messageList = nil; - } + messageList = ms_list_free_with_data(messageList, (void (*)(void *))linphone_chat_message_unref); } - (void)updateData { @@ -72,6 +69,14 @@ } - (void)addChatEntry:(LinphoneChatMessage *)chat { + // do not add the same message multiple times. It can happen on iPad since in fragment + // mode, "message received" notification will reload tabledata, retrieving all history + // and THEN addChatEntry will be called, requesting the newest message to be added again + if (messageList && + (linphone_chat_message_get_storage_id(chat) == + linphone_chat_message_get_storage_id(ms_list_nth_data(messageList, ms_list_size(messageList) - 1)))) { + return; + } messageList = ms_list_append(messageList, linphone_chat_message_ref(chat)); int pos = ms_list_size(messageList) - 1; diff --git a/Classes/ChatConversationView.m b/Classes/ChatConversationView.m index e5066e9e6..8e142b5be 100644 --- a/Classes/ChatConversationView.m +++ b/Classes/ChatConversationView.m @@ -78,7 +78,7 @@ static UICompositeViewDescription *compositeDescription = nil; } _messageField.minNumberOfLines = 1; - _messageField.maxNumberOfLines = ([LinphoneManager runningOnIpad]) ? 10 : 3; + _messageField.maxNumberOfLines = IPAD ? 10 : 3; _messageField.delegate = self; _messageField.font = [UIFont systemFontOfSize:18.0f]; _messageField.contentInset = UIEdgeInsetsMake(-15, 0, 0, 0); @@ -320,12 +320,12 @@ static UICompositeViewDescription *compositeDescription = nil; if (from == NULL || chat == NULL) { return; } + char *fromStr = linphone_address_as_string_uri_only(from); const LinphoneAddress *cr_from = linphone_chat_room_get_peer_address(chatRoom); char *cr_from_string = linphone_address_as_string_uri_only(cr_from); if (fromStr && cr_from_string) { - if (strcasecmp(cr_from_string, fromStr) == 0) { if ([UIApplication sharedApplication].applicationState != UIApplicationStateBackground) { linphone_chat_room_mark_as_read(room); @@ -515,7 +515,7 @@ static UICompositeViewDescription *compositeDescription = nil; } - (IBAction)onCallClick:(id)sender { - [LinphoneManager.instance call:linphone_chat_room_get_peer_address(chatRoom) transfer:NO]; + [LinphoneManager.instance call:linphone_chat_room_get_peer_address(chatRoom)]; } - (IBAction)onListSwipe:(id)sender { diff --git a/Classes/ChatsListTableView.m b/Classes/ChatsListTableView.m index 29756c6fe..5085209a2 100644 --- a/Classes/ChatsListTableView.m +++ b/Classes/ChatsListTableView.m @@ -121,7 +121,7 @@ static void chatTable_free_chatrooms(void *data) { if (IPAD) { // reset conversation view since in fragment mode, conversations are relative to current data // select first conversation if any - if ([self totalNumberOfItems] > 0) { + if (data != NULL) { ChatConversationView *view = VIEW(ChatConversationView); [view setChatRoom:(LinphoneChatRoom *)ms_list_nth_data(data, 0)]; } diff --git a/Classes/ContactsListView.m b/Classes/ContactsListView.m index 32d745fd2..881032225 100644 --- a/Classes/ContactsListView.m +++ b/Classes/ContactsListView.m @@ -108,6 +108,14 @@ static UICompositeViewDescription *compositeDescription = nil; #pragma mark - ViewController Functions +- (void)viewDidLoad { + [super viewDidLoad]; + [self changeView:ContactsLinphone]; + if ([tableController totalNumberOfItems] == 0) { + [self changeView:ContactsAll]; + } +} + - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; @@ -135,11 +143,6 @@ static UICompositeViewDescription *compositeDescription = nil; } } -- (void)viewDidLoad { - [super viewDidLoad]; - [self changeView:ContactsAll]; -} - #pragma mark - - (void)changeView:(ContactsCategory)view { diff --git a/Classes/DialerView.h b/Classes/DialerView.h index 7c745d1dd..edf1247cb 100644 --- a/Classes/DialerView.h +++ b/Classes/DialerView.h @@ -23,22 +23,16 @@ #import "UICamSwitch.h" #import "UICallButton.h" -#import "UITransferButton.h" #import "UIDigitButton.h" @interface DialerView : TPMultiLayoutViewController { } -- (void)setAddress:(NSString *)address; - -@property(nonatomic, assign) BOOL transferMode; @property(nonatomic, strong) IBOutlet UITextField *addressField; @property(nonatomic, strong) IBOutlet UIButton *addContactButton; @property(nonatomic, strong) IBOutlet UICallButton *callButton; -@property(nonatomic, strong) IBOutlet UICallButton *addCallButton; -@property(nonatomic, strong) IBOutlet UITransferButton *transferButton; @property(nonatomic, strong) IBOutlet UIButton *backButton; @property(weak, nonatomic) IBOutlet UIIconButton *backspaceButton; @@ -64,4 +58,6 @@ - (IBAction)onAddressChange:(id)sender; - (IBAction)onBackspaceClick:(id)sender; +- (void)setAddress:(NSString *)address; + @end diff --git a/Classes/DialerView.m b/Classes/DialerView.m index c0aab3270..61d30a051 100644 --- a/Classes/DialerView.m +++ b/Classes/DialerView.m @@ -25,48 +25,6 @@ @implementation DialerView -@synthesize transferMode; - -@synthesize addressField; -@synthesize addContactButton; -@synthesize backButton; -@synthesize addCallButton; -@synthesize transferButton; -@synthesize callButton; -@synthesize backspaceButton; - -@synthesize oneButton; -@synthesize twoButton; -@synthesize threeButton; -@synthesize fourButton; -@synthesize fiveButton; -@synthesize sixButton; -@synthesize sevenButton; -@synthesize eightButton; -@synthesize nineButton; -@synthesize starButton; -@synthesize zeroButton; -@synthesize hashButton; - -@synthesize backgroundView; -@synthesize videoPreview; -@synthesize videoCameraSwitch; - -#pragma mark - Lifecycle Functions - -- (id)init { - self = [super initWithNibName:NSStringFromClass(self.class) bundle:[NSBundle mainBundle]]; - if (self) { - transferMode = FALSE; - } - return self; -} - -- (void)dealloc { - // Remove all observers - [NSNotificationCenter.defaultCenter removeObserver:self]; -} - #pragma mark - UICompositeViewDelegate Functions static UICompositeViewDescription *compositeDescription = nil; @@ -108,42 +66,35 @@ static UICompositeViewDescription *compositeDescription = nil; name:kLinphoneCoreUpdate object:nil]; - // technically not needed, but older versions of linphone had this button - // disabled by default. In this case, updating by pushing a new version with - // xcode would result in the callbutton being disabled all the time. - // We force it enabled anyway now. - [callButton setEnabled:TRUE]; - // Update on show LinphoneManager *mgr = LinphoneManager.instance; - LinphoneCore *lc = LC; - LinphoneCall *call = linphone_core_get_current_call(lc); + LinphoneCall *call = linphone_core_get_current_call(LC); LinphoneCallState state = (call != NULL) ? linphone_call_get_state(call) : 0; [self callUpdate:call state:state]; if (IPAD) { - BOOL videoEnabled = linphone_core_video_display_enabled(lc); + BOOL videoEnabled = linphone_core_video_display_enabled(LC); BOOL previewPref = [mgr lpConfigBoolForKey:@"preview_preference"]; if (videoEnabled && previewPref) { - linphone_core_set_native_preview_window_id(lc, (__bridge void *)(videoPreview)); + linphone_core_set_native_preview_window_id(LC, (__bridge void *)(_videoPreview)); - if (!linphone_core_video_preview_enabled(lc)) { - linphone_core_enable_video_preview(lc, TRUE); + if (!linphone_core_video_preview_enabled(LC)) { + linphone_core_enable_video_preview(LC, TRUE); } - [backgroundView setHidden:FALSE]; - [videoCameraSwitch setHidden:FALSE]; + [_backgroundView setHidden:FALSE]; + [_videoCameraSwitch setHidden:FALSE]; } else { - linphone_core_set_native_preview_window_id(lc, NULL); - linphone_core_enable_video_preview(lc, FALSE); - [backgroundView setHidden:TRUE]; - [videoCameraSwitch setHidden:TRUE]; + linphone_core_set_native_preview_window_id(LC, NULL); + linphone_core_enable_video_preview(LC, FALSE); + [_backgroundView setHidden:TRUE]; + [_videoCameraSwitch setHidden:TRUE]; } } else { - linphone_core_enable_video_preview(lc, FALSE); + linphone_core_enable_video_preview(LC, FALSE); } - [addressField setText:@""]; + [_addressField setText:@""]; } - (void)viewWillDisappear:(BOOL)animated { @@ -154,37 +105,37 @@ static UICompositeViewDescription *compositeDescription = nil; - (void)viewDidLoad { [super viewDidLoad]; - [zeroButton setDigit:'0']; - [oneButton setDigit:'1']; - [twoButton setDigit:'2']; - [threeButton setDigit:'3']; - [fourButton setDigit:'4']; - [fiveButton setDigit:'5']; - [sixButton setDigit:'6']; - [sevenButton setDigit:'7']; - [eightButton setDigit:'8']; - [nineButton setDigit:'9']; - [starButton setDigit:'*']; - [hashButton setDigit:'#']; + [_zeroButton setDigit:'0']; + [_oneButton setDigit:'1']; + [_twoButton setDigit:'2']; + [_threeButton setDigit:'3']; + [_fourButton setDigit:'4']; + [_fiveButton setDigit:'5']; + [_sixButton setDigit:'6']; + [_sevenButton setDigit:'7']; + [_eightButton setDigit:'8']; + [_nineButton setDigit:'9']; + [_starButton setDigit:'*']; + [_hashButton setDigit:'#']; - [addressField setAdjustsFontSizeToFitWidth:TRUE]; // Not put it in IB: issue with placeholder size + [_addressField setAdjustsFontSizeToFitWidth:TRUE]; // Not put it in IB: issue with placeholder size UILongPressGestureRecognizer *backspaceLongGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(onBackspaceLongClick:)]; - [backspaceButton addGestureRecognizer:backspaceLongGesture]; + [_backspaceButton addGestureRecognizer:backspaceLongGesture]; UILongPressGestureRecognizer *zeroLongGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(onZeroLongClick:)]; - [zeroButton addGestureRecognizer:zeroLongGesture]; + [_zeroButton addGestureRecognizer:zeroLongGesture]; UILongPressGestureRecognizer *oneLongGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(onOneLongClick:)]; - [oneButton addGestureRecognizer:oneLongGesture]; + [_oneButton addGestureRecognizer:oneLongGesture]; if (IPAD) { if (LinphoneManager.instance.frontCamId != nil) { // only show camera switch button if we have more than 1 camera - [videoCameraSwitch setHidden:FALSE]; + [_videoCameraSwitch setHidden:FALSE]; } } } @@ -194,23 +145,23 @@ static UICompositeViewDescription *compositeDescription = nil; [super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration]; switch (toInterfaceOrientation) { case UIInterfaceOrientationPortrait: - [videoPreview setTransform:CGAffineTransformMakeRotation(0)]; + [_videoPreview setTransform:CGAffineTransformMakeRotation(0)]; break; case UIInterfaceOrientationPortraitUpsideDown: - [videoPreview setTransform:CGAffineTransformMakeRotation(M_PI)]; + [_videoPreview setTransform:CGAffineTransformMakeRotation(M_PI)]; break; case UIInterfaceOrientationLandscapeLeft: - [videoPreview setTransform:CGAffineTransformMakeRotation(M_PI / 2)]; + [_videoPreview setTransform:CGAffineTransformMakeRotation(M_PI / 2)]; break; case UIInterfaceOrientationLandscapeRight: - [videoPreview setTransform:CGAffineTransformMakeRotation(-M_PI / 2)]; + [_videoPreview setTransform:CGAffineTransformMakeRotation(-M_PI / 2)]; break; default: break; } CGRect frame = self.view.frame; frame.origin = CGPointMake(0, 0); - videoPreview.frame = frame; + _videoPreview.frame = frame; _padView.hidden = !IPAD && UIInterfaceOrientationIsLandscape(toInterfaceOrientation); } @@ -224,15 +175,14 @@ static UICompositeViewDescription *compositeDescription = nil; - (void)coreUpdateEvent:(NSNotification *)notif { if (IPAD) { - LinphoneCore *lc = LC; - if (linphone_core_video_display_enabled(lc) && linphone_core_video_preview_enabled(lc)) { - linphone_core_set_native_preview_window_id(lc, (__bridge void *)(videoPreview)); - [backgroundView setHidden:FALSE]; - [videoCameraSwitch setHidden:FALSE]; + if (linphone_core_video_display_enabled(LC) && linphone_core_video_preview_enabled(LC)) { + linphone_core_set_native_preview_window_id(LC, (__bridge void *)(_videoPreview)); + [_backgroundView setHidden:FALSE]; + [_videoCameraSwitch setHidden:FALSE]; } else { - linphone_core_set_native_preview_window_id(lc, NULL); - [backgroundView setHidden:TRUE]; - [videoCameraSwitch setHidden:TRUE]; + linphone_core_set_native_preview_window_id(LC, NULL); + [_backgroundView setHidden:TRUE]; + [_videoCameraSwitch setHidden:TRUE]; } } } @@ -309,14 +259,33 @@ static UICompositeViewDescription *compositeDescription = nil; [self presentMailViewWithTitle:appName forRecipients:@[ logsAddress ] attachLogs:true]; }]; - BOOL debugEnabled = [LinphoneManager.instance lpConfigBoolForKey:@"debugenable_preference"]; + int debugLevel = [LinphoneManager.instance lpConfigIntForKey:@"debugenable_preference"]; + BOOL debugEnabled = (debugLevel >= ORTP_DEBUG && debugLevel < ORTP_ERROR); NSString *actionLog = (debugEnabled ? NSLocalizedString(@"Disable logs", nil) : NSLocalizedString(@"Enable logs", nil)); - [alertView addButtonWithTitle:actionLog + [alertView + addButtonWithTitle:actionLog + block:^{ + int newDebugLevel = debugEnabled ? ORTP_ERROR : ORTP_DEBUG; + [LinphoneManager.instance lpConfigSetInt:newDebugLevel forKey:@"debugenable_preference"]; + [Log enableLogs:newDebugLevel]; + }]; + + [alertView addButtonWithTitle:NSLocalizedString(@"Remove account(s) and self destruct", nil) block:^{ - BOOL enabled = !debugEnabled; - [LinphoneManager.instance lpConfigSetBool:enabled forKey:@"debugenable_preference"]; - [Log enableLogs:enabled]; + linphone_core_clear_proxy_config([LinphoneManager getLc]); + linphone_core_clear_all_auth_info([LinphoneManager getLc]); + [LinphoneManager.instance destroyLinphoneCore]; + if ([NSFileManager.defaultManager + isDeletableFileAtPath:[LinphoneManager documentFile:@"linphonerc"]] == YES) { + [NSFileManager.defaultManager + removeItemAtPath:[LinphoneManager documentFile:@"linphonerc"] + error:nil]; + } +#ifdef DEBUG + [LinphoneManager instanceRelease]; +#endif + [UIApplication sharedApplication].keyWindow.rootViewController = nil; }]; [alertView show]; @@ -328,24 +297,14 @@ static UICompositeViewDescription *compositeDescription = nil; #pragma mark - - (void)callUpdate:(LinphoneCall *)call state:(LinphoneCallState)state { - LinphoneCore *lc = LC; - BOOL callInProgress = (linphone_core_get_calls_nb(lc) > 0); - addCallButton.hidden = (!callInProgress || transferMode); - transferButton.hidden = (!callInProgress || !transferMode); - addContactButton.hidden = callButton.hidden = callInProgress; - backButton.hidden = !callInProgress; - [callButton updateVideoPolicy]; + BOOL callInProgress = (linphone_core_get_calls_nb(LC) > 0); + _addContactButton.hidden = callInProgress; + _backButton.hidden = !callInProgress; + [_callButton updateIcon]; } - (void)setAddress:(NSString *)address { - [addressField setText:address]; -} - -- (void)setTransferMode:(BOOL)atransferMode { - transferMode = atransferMode; - LinphoneCall *call = linphone_core_get_current_call(LC); - LinphoneCallState state = (call != NULL) ? linphone_call_get_state(call) : 0; - [self callUpdate:call state:state]; + [_addressField setText:address]; } #pragma mark - UITextFieldDelegate Functions @@ -358,12 +317,12 @@ static UICompositeViewDescription *compositeDescription = nil; } - (BOOL)textFieldShouldReturn:(UITextField *)textField { - if (textField == addressField) { - [addressField resignFirstResponder]; + if (textField == _addressField) { + [_addressField resignFirstResponder]; } if (textField.text.length > 0) { LinphoneAddress *addr = linphone_core_interpret_url(LC, textField.text.UTF8String); - [LinphoneManager.instance call:addr transfer:FALSE]; + [LinphoneManager.instance call:addr]; if (addr) linphone_address_destroy(addr); } @@ -385,7 +344,7 @@ static UICompositeViewDescription *compositeDescription = nil; - (IBAction)onAddContactClick:(id)event { [ContactSelection setSelectionMode:ContactSelectionModeEdit]; - [ContactSelection setAddAddress:[addressField text]]; + [ContactSelection setAddAddress:[_addressField text]]; [ContactSelection setSipFilter:nil]; [ContactSelection setNameOrEmailFilter:nil]; [ContactSelection enableEmailFilter:FALSE]; @@ -397,28 +356,28 @@ static UICompositeViewDescription *compositeDescription = nil; } - (IBAction)onAddressChange:(id)sender { - if ([self displayDebugPopup:self.addressField.text]) { - self.addressField.text = @""; + if ([self displayDebugPopup:_addressField.text]) { + _addressField.text = @""; } - addContactButton.enabled = backspaceButton.enabled = addCallButton.enabled = transferButton.enabled = - ([[addressField text] length] > 0); + _addContactButton.enabled = _backspaceButton.enabled = ([[_addressField text] length] > 0); } - (IBAction)onBackspaceClick:(id)sender { - if ([addressField.text length] > 0) { - [addressField setText:[addressField.text substringToIndex:[addressField.text length] - 1]]; + if ([_addressField.text length] > 0) { + [_addressField setText:[_addressField.text substringToIndex:[_addressField.text length] - 1]]; } } - (void)onBackspaceLongClick:(id)sender { - [addressField setText:@""]; + [_addressField setText:@""]; } - (void)onZeroLongClick:(id)sender { // replace last character with a '+' NSString *newAddress = - [[self.addressField.text substringToIndex:[self.addressField.text length] - 1] stringByAppendingString:@"+"]; - [self.addressField setText:newAddress]; + [[_addressField.text substringToIndex:[_addressField.text length] - 1] stringByAppendingString:@"+"]; + [_addressField setText:newAddress]; + linphone_core_stop_dtmf(LC); } - (void)onOneLongClick:(id)sender { @@ -427,10 +386,11 @@ static UICompositeViewDescription *compositeDescription = nil; LinphoneAddress *addr = linphone_core_interpret_url(LC, voiceMail ? voiceMail.UTF8String : NULL); if (addr) { linphone_address_set_display_name(addr, NSLocalizedString(@"Voice mail", nil).UTF8String); - [lm call:addr transfer:FALSE]; + [lm call:addr]; linphone_address_destroy(addr); } else { LOGE(@"Cannot call voice mail because URI not set or invalid!"); } + linphone_core_stop_dtmf(LC); } @end diff --git a/Classes/HistoryDetailsView.m b/Classes/HistoryDetailsView.m index 37cbc7b33..521b7bceb 100644 --- a/Classes/HistoryDetailsView.m +++ b/Classes/HistoryDetailsView.m @@ -166,7 +166,7 @@ static UICompositeViewDescription *compositeDescription = nil; - (IBAction)onCallClick:(id)event { LinphoneAddress *addr = linphone_call_log_get_remote_address(callLog); - [LinphoneManager.instance call:addr transfer:NO]; + [LinphoneManager.instance call:addr]; } - (IBAction)onChatClick:(id)event { diff --git a/Classes/HistoryListTableView.m b/Classes/HistoryListTableView.m index 5ef0ff972..0ba85acd0 100644 --- a/Classes/HistoryListTableView.m +++ b/Classes/HistoryListTableView.m @@ -228,7 +228,7 @@ [cell onDetails:self]; } else { LinphoneAddress *addr = linphone_call_log_get_remote_address(callLog); - [LinphoneManager.instance call:addr transfer:NO]; + [LinphoneManager.instance call:addr]; } } } diff --git a/Classes/KIF b/Classes/KIF index c01c06361..2e2e314a4 160000 --- a/Classes/KIF +++ b/Classes/KIF @@ -1 +1 @@ -Subproject commit c01c063616dbdab05bea25eb94c7643a52f2b7dc +Subproject commit 2e2e314a44aa9e3949fd54c75baff376af526493 diff --git a/Classes/LaunchScreen.xib b/Classes/LaunchScreen.xib new file mode 100644 index 000000000..a5c5107e4 --- /dev/null +++ b/Classes/LaunchScreen.xib @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Classes/LinphoneAppDelegate.h b/Classes/LinphoneAppDelegate.h index a0ec499e1..edda21b1b 100644 --- a/Classes/LinphoneAppDelegate.h +++ b/Classes/LinphoneAppDelegate.h @@ -30,6 +30,7 @@ } - (void)processRemoteNotification:(NSDictionary*)userInfo; +- (void)registerForNotifications:(UIApplication *)app; @property (nonatomic, retain) UIAlertView *waitingIndicator; @property (nonatomic, retain) NSString *configURL; diff --git a/Classes/LinphoneAppDelegate.m b/Classes/LinphoneAppDelegate.m index 32e7e37b4..d1bda420b 100644 --- a/Classes/LinphoneAppDelegate.m +++ b/Classes/LinphoneAppDelegate.m @@ -53,8 +53,7 @@ - (void)applicationWillResignActive:(UIApplication *)application { LOGI(@"%@", NSStringFromSelector(_cmd)); - LinphoneCore *lc = LC; - LinphoneCall *call = linphone_core_get_current_call(lc); + LinphoneCall *call = linphone_core_get_current_call(LC); if (call) { /* save call context */ @@ -84,8 +83,7 @@ [instance becomeActive]; - LinphoneCore *lc = LC; - LinphoneCall *call = linphone_core_get_current_call(lc); + LinphoneCall *call = linphone_core_get_current_call(LC); if (call) { if (call == instance->currentCallContextBeforeGoingBackground.call) { @@ -104,27 +102,44 @@ } - (UIUserNotificationCategory *)getMessageNotificationCategory { + NSArray *actions; - UIMutableUserNotificationAction *reply = [[UIMutableUserNotificationAction alloc] init]; - reply.identifier = @"reply"; - reply.title = NSLocalizedString(@"Reply", nil); - reply.activationMode = UIUserNotificationActivationModeForeground; - reply.destructive = NO; - reply.authenticationRequired = YES; + if ([[UIDevice.currentDevice systemVersion] floatValue] < 9 || + [LinphoneManager.instance lpConfigBoolForKey:@"show_msg_in_notif"] == NO) { - UIMutableUserNotificationAction *mark_read = [[UIMutableUserNotificationAction alloc] init]; - mark_read.identifier = @"mark_read"; - mark_read.title = NSLocalizedString(@"Mark Read", nil); - mark_read.activationMode = UIUserNotificationActivationModeBackground; - mark_read.destructive = NO; - mark_read.authenticationRequired = NO; + UIMutableUserNotificationAction *reply = [[UIMutableUserNotificationAction alloc] init]; + reply.identifier = @"reply"; + reply.title = NSLocalizedString(@"Reply", nil); + reply.activationMode = UIUserNotificationActivationModeForeground; + reply.destructive = NO; + reply.authenticationRequired = YES; - NSArray *localRingActions = @[ mark_read, reply ]; + UIMutableUserNotificationAction *mark_read = [[UIMutableUserNotificationAction alloc] init]; + mark_read.identifier = @"mark_read"; + mark_read.title = NSLocalizedString(@"Mark Read", nil); + mark_read.activationMode = UIUserNotificationActivationModeBackground; + mark_read.destructive = NO; + mark_read.authenticationRequired = NO; + + actions = @[ mark_read, reply ]; + } else { + // iOS 9 allows for inline reply. We don't propose mark_read in this case + UIMutableUserNotificationAction *reply_inline = [[UIMutableUserNotificationAction alloc] init]; + + reply_inline.identifier = @"reply_inline"; + reply_inline.title = NSLocalizedString(@"Reply", nil); + reply_inline.activationMode = UIUserNotificationActivationModeBackground; + reply_inline.destructive = NO; + reply_inline.authenticationRequired = NO; + reply_inline.behavior = UIUserNotificationActionBehaviorTextInput; + + actions = @[ reply_inline ]; + } UIMutableUserNotificationCategory *localRingNotifAction = [[UIMutableUserNotificationCategory alloc] init]; localRingNotifAction.identifier = @"incoming_msg"; - [localRingNotifAction setActions:localRingActions forContext:UIUserNotificationActionContextDefault]; - [localRingNotifAction setActions:localRingActions forContext:UIUserNotificationActionContextMinimal]; + [localRingNotifAction setActions:actions forContext:UIUserNotificationActionContextDefault]; + [localRingNotifAction setActions:actions forContext:UIUserNotificationActionContextMinimal]; return localRingNotifAction; } @@ -154,14 +169,8 @@ return localRingNotifAction; } -- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - - UIApplication *app = [UIApplication sharedApplication]; - UIApplicationState state = app.applicationState; - - LinphoneManager *instance = LinphoneManager.instance; - BOOL background_mode = [instance lpConfigBoolForKey:@"backgroundmode_preference"]; - BOOL start_at_boot = [instance lpConfigBoolForKey:@"start_at_boot_preference"]; +- (void)registerForNotifications:(UIApplication *)app { + LinphoneManager *instance = [LinphoneManager instance]; if ([app respondsToSelector:@selector(registerUserNotificationSettings:)]) { /* iOS8 notifications can be actioned! Awesome: */ @@ -178,12 +187,25 @@ [app registerForRemoteNotifications]; } } else { + /* iOS7 and below */ if (!instance.isTesting) { NSUInteger notifTypes = UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeBadge; [app registerForRemoteNotificationTypes:notifTypes]; } } +} + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + + UIApplication *app = [UIApplication sharedApplication]; + UIApplicationState state = app.applicationState; + + LinphoneManager *instance = [LinphoneManager instance]; + BOOL background_mode = [instance lpConfigBoolForKey:@"backgroundmode_preference"]; + BOOL start_at_boot = [instance lpConfigBoolForKey:@"start_at_boot_preference"]; + + [self registerForNotifications:app]; if (state == UIApplicationStateBackground) { // we've been woken up directly to background; @@ -276,9 +298,8 @@ NSString *loc_key = [alert objectForKey:@"loc-key"]; /*if we receive a remote notification, it is probably because our TCP background socket was no more working. As a result, break it and refresh registers in order to make sure to receive incoming INVITE or MESSAGE*/ - LinphoneCore *lc = LC; - if (linphone_core_get_calls(lc) == NULL) { // if there are calls, obviously our TCP socket shall be working - linphone_core_set_network_reachable(lc, FALSE); + if (linphone_core_get_calls(LC) == NULL) { // if there are calls, obviously our TCP socket shall be working + linphone_core_set_network_reachable(LC, FALSE); LinphoneManager.instance.connectivity = none; /*force connectivity to be discovered again*/ [LinphoneManager.instance refreshRegisters]; if (loc_key != nil) { @@ -369,12 +390,11 @@ userInfo:nil repeats:FALSE]; - LinphoneCore *lc = LC; // If no call is yet received at this time, then force Linphone to drop the current socket and make new one to // register, so that we get // a better chance to receive the INVITE. - if (linphone_core_get_calls(lc) == NULL) { - linphone_core_set_network_reachable(lc, FALSE); + if (linphone_core_get_calls(LC) == NULL) { + linphone_core_set_network_reachable(LC, FALSE); lm.connectivity = none; /*force connectivity to be discovered again*/ [lm refreshRegisters]; } @@ -406,17 +426,15 @@ completionHandler:(void (^)())completionHandler { LOGI(@"%@", NSStringFromSelector(_cmd)); if ([[UIDevice currentDevice].systemVersion floatValue] >= 8) { - - LinphoneCore *lc = LC; LOGI(@"%@", NSStringFromSelector(_cmd)); if ([notification.category isEqualToString:@"incoming_call"]) { if ([identifier isEqualToString:@"answer"]) { // use the standard handler [self application:application didReceiveLocalNotification:notification]; } else if ([identifier isEqualToString:@"decline"]) { - LinphoneCall *call = linphone_core_get_current_call(lc); + LinphoneCall *call = linphone_core_get_current_call(LC); if (call) - linphone_core_decline_call(lc, call, LinphoneReasonDeclined); + linphone_core_decline_call(LC, call, LinphoneReasonDeclined); } } else if ([notification.category isEqualToString:@"incoming_msg"]) { if ([identifier isEqualToString:@"reply"]) { @@ -424,7 +442,7 @@ [self application:application didReceiveLocalNotification:notification]; } else if ([identifier isEqualToString:@"mark_read"]) { NSString *from = [notification.userInfo objectForKey:@"from_addr"]; - LinphoneChatRoom *room = linphone_core_get_chat_room_from_uri(lc, [from UTF8String]); + LinphoneChatRoom *room = linphone_core_get_chat_room_from_uri(LC, [from UTF8String]); if (room) { linphone_chat_room_mark_as_read(room); TabBarView *tab = (TabBarView *)[PhoneMainView.instance.mainViewController @@ -438,6 +456,25 @@ completionHandler(); } +- (void)application:(UIApplication *)application + handleActionWithIdentifier:(NSString *)identifier + forLocalNotification:(UILocalNotification *)notification + withResponseInfo:(NSDictionary *)responseInfo + completionHandler:(void (^)())completionHandler { + + if ([notification.category isEqualToString:@"incoming_msg"] && [identifier isEqualToString:@"reply_inline"]) { + LinphoneCore *lc = [LinphoneManager getLc]; + NSString *replyText = [responseInfo objectForKey:UIUserNotificationActionResponseTypedTextKey]; + NSString *from = [notification.userInfo objectForKey:@"from_addr"]; + LinphoneChatRoom *room = linphone_core_get_chat_room_from_uri(lc, [from UTF8String]); + if (room) { + LinphoneChatMessage *msg = linphone_chat_room_create_message(room, replyText.UTF8String); + linphone_chat_room_send_chat_message(room, msg); + linphone_chat_room_mark_as_read(room); + } + } +} + - (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo diff --git a/Classes/LinphoneCoreSettingsStore.m b/Classes/LinphoneCoreSettingsStore.m index e2a511700..0cd7a9672 100644 --- a/Classes/LinphoneCoreSettingsStore.m +++ b/Classes/LinphoneCoreSettingsStore.m @@ -99,14 +99,13 @@ } - (void)transformCodecsToKeys:(const MSList *)codecs { - LinphoneCore *lc = LC; const MSList *elem = codecs; for (; elem != NULL; elem = elem->next) { PayloadType *pt = (PayloadType *)elem->data; NSString *pref = [LinphoneManager getPreferenceForCodec:pt->mime_type withRate:pt->clock_rate]; if (pref) { - bool_t value = linphone_core_payload_type_enabled(lc, pt); + bool_t value = linphone_core_payload_type_enabled(LC, pt); [self setBool:value forKey:pref]; } else { LOGW(@"Codec %s/%i supported by core is not shown in iOS app config view.", pt->mime_type, pt->clock_rate); @@ -115,8 +114,7 @@ } - (void)transformAccountToKeys:(NSString *)username { - LinphoneCore *lc = LC; - const MSList *proxies = linphone_core_get_proxy_config_list(lc); + const MSList *proxies = linphone_core_get_proxy_config_list(LC); while (username && proxies && strcmp(username.UTF8String, linphone_address_get_username(linphone_proxy_config_get_identity_address(proxies->data))) != 0) { @@ -187,11 +185,11 @@ [self setBool:(linphone_proxy_config_get_route(proxy) != NULL) forKey:@"account_outbound_proxy_preference"]; [self setBool:linphone_proxy_config_avpf_enabled(proxy) forKey:@"account_avpf_preference"]; [self setBool:linphone_proxy_config_register_enabled(proxy) forKey:@"account_is_enabled_preference"]; - [self setBool:(linphone_core_get_default_proxy_config(lc) == proxy) + [self setBool:(linphone_core_get_default_proxy_config(LC) == proxy) forKey:@"account_is_default_preference"]; const LinphoneAuthInfo *ai = linphone_core_find_auth_info( - lc, NULL, [self stringForKey:@"account_mandatory_username_preference"].UTF8String, + LC, NULL, [self stringForKey:@"account_mandatory_username_preference"].UTF8String, [self stringForKey:@"account_mandatory_domain_preference"].UTF8String); if (ai) { [self setCString:linphone_auth_info_get_userid(ai) forKey:@"account_userid_preference"]; @@ -200,7 +198,7 @@ [self setCString:linphone_auth_info_get_ha1(ai) forKey:@"ha1_preference"]; } - int idx = ms_list_index(linphone_core_get_proxy_config_list(lc), proxy); + int idx = ms_list_index(linphone_core_get_proxy_config_list(LC), proxy); [self setInteger:idx forKey:@"current_proxy_config_preference"]; int expires = linphone_proxy_config_get_expires(proxy); @@ -219,7 +217,6 @@ - (void)transformLinphoneCoreToKeys { LinphoneManager *lm = LinphoneManager.instance; - LinphoneCore *lc = LC; // root section { @@ -232,7 +229,7 @@ forKey:key]; } - [self setBool:linphone_core_video_display_enabled(lc) forKey:@"enable_video_preference"]; + [self setBool:linphone_core_video_display_enabled(LC) forKey:@"enable_video_preference"]; [self setBool:[LinphoneManager.instance lpConfigBoolForKey:@"auto_answer"] forKey:@"enable_auto_answer_preference"]; [self setBool:[lm lpConfigBoolForKey:@"account_mandatory_advanced_preference"] @@ -244,9 +241,9 @@ // audio section { - [self transformCodecsToKeys:linphone_core_get_audio_codecs(lc)]; - [self setFloat:linphone_core_get_playback_gain_db(lc) forKey:@"playback_gain_preference"]; - [self setFloat:linphone_core_get_mic_gain_db(lc) forKey:@"microphone_gain_preference"]; + [self transformCodecsToKeys:linphone_core_get_audio_codecs(LC)]; + [self setFloat:linphone_core_get_playback_gain_db(LC) forKey:@"playback_gain_preference"]; + [self setFloat:linphone_core_get_mic_gain_db(LC) forKey:@"microphone_gain_preference"]; [self setInteger:[lm lpConfigIntForKey:@"codec_bitrate_limit" inSection:@"audio" withDefault:kLinphoneAudioVbrCodecDefaultBitrate] @@ -257,19 +254,19 @@ // video section { - [self transformCodecsToKeys:linphone_core_get_video_codecs(lc)]; + [self transformCodecsToKeys:linphone_core_get_video_codecs(LC)]; const LinphoneVideoPolicy *pol; - pol = linphone_core_get_video_policy(lc); + pol = linphone_core_get_video_policy(LC); [self setBool:(pol->automatically_initiate) forKey:@"start_video_preference"]; [self setBool:(pol->automatically_accept) forKey:@"accept_video_preference"]; - [self setBool:linphone_core_self_view_enabled(lc) forKey:@"self_video_preference"]; + [self setBool:linphone_core_self_view_enabled(LC) forKey:@"self_video_preference"]; BOOL previewEnabled = [lm lpConfigBoolForKey:@"preview_preference" withDefault:YES]; [self setBool:IPAD && previewEnabled forKey:@"preview_preference"]; - const char *preset = linphone_core_get_video_preset(lc); + const char *preset = linphone_core_get_video_preset(LC); [self setCString:preset ? preset : "default" forKey:@"video_preset_preference"]; - MSVideoSize vsize = linphone_core_get_preferred_video_size(lc); + MSVideoSize vsize = linphone_core_get_preferred_video_size(LC); int index; if ((vsize.width == MS_VIDEO_SIZE_720P_W) && (vsize.height == MS_VIDEO_SIZE_720P_H)) { index = 0; @@ -279,17 +276,17 @@ index = 2; } [self setInteger:index forKey:@"video_preferred_size_preference"]; - [self setInteger:linphone_core_get_preferred_framerate(lc) forKey:@"video_preferred_fps_preference"]; - [self setInteger:linphone_core_get_download_bandwidth(lc) forKey:@"download_bandwidth_preference"]; + [self setInteger:linphone_core_get_preferred_framerate(LC) forKey:@"video_preferred_fps_preference"]; + [self setInteger:linphone_core_get_download_bandwidth(LC) forKey:@"download_bandwidth_preference"]; } // call section { - [self setBool:linphone_core_get_use_info_for_dtmf(lc) forKey:@"sipinfo_dtmf_preference"]; - [self setBool:linphone_core_get_use_rfc2833_for_dtmf(lc) forKey:@"rfc_dtmf_preference"]; + [self setBool:linphone_core_get_use_info_for_dtmf(LC) forKey:@"sipinfo_dtmf_preference"]; + [self setBool:linphone_core_get_use_rfc2833_for_dtmf(LC) forKey:@"rfc_dtmf_preference"]; - [self setInteger:linphone_core_get_inc_timeout(lc) forKey:@"incoming_call_timeout_preference"]; - [self setInteger:linphone_core_get_in_call_timeout(lc) forKey:@"in_call_timeout_preference"]; + [self setInteger:linphone_core_get_inc_timeout(LC) forKey:@"incoming_call_timeout_preference"]; + [self setInteger:linphone_core_get_in_call_timeout(LC) forKey:@"in_call_timeout_preference"]; [self setBool:[lm lpConfigBoolForKey:@"repeat_call_notification"] forKey:@"repeat_call_notification_preference"]; @@ -299,15 +296,15 @@ { [self setBool:[lm lpConfigBoolForKey:@"edge_opt_preference" withDefault:NO] forKey:@"edge_opt_preference"]; [self setBool:[lm lpConfigBoolForKey:@"wifi_only_preference" withDefault:NO] forKey:@"wifi_only_preference"]; - [self setCString:linphone_core_get_stun_server(lc) forKey:@"stun_preference"]; - [self setBool:linphone_core_get_firewall_policy(lc) == LinphonePolicyUseIce forKey:@"ice_preference"]; + [self setCString:linphone_core_get_stun_server(LC) forKey:@"stun_preference"]; + [self setBool:linphone_core_get_firewall_policy(LC) == LinphonePolicyUseIce forKey:@"ice_preference"]; int random_port_preference = [lm lpConfigIntForKey:@"random_port_preference" withDefault:1]; [self setInteger:random_port_preference forKey:@"random_port_preference"]; int port = [lm lpConfigIntForKey:@"port_preference" withDefault:5060]; [self setInteger:port forKey:@"port_preference"]; { int minPort, maxPort; - linphone_core_get_audio_port_range(lc, &minPort, &maxPort); + linphone_core_get_audio_port_range(LC, &minPort, &maxPort); if (minPort != maxPort) [self setObject:[NSString stringWithFormat:@"%d-%d", minPort, maxPort] forKey:@"audio_port_preference"]; else @@ -315,14 +312,14 @@ } { int minPort, maxPort; - linphone_core_get_video_port_range(lc, &minPort, &maxPort); + linphone_core_get_video_port_range(LC, &minPort, &maxPort); if (minPort != maxPort) [self setObject:[NSString stringWithFormat:@"%d-%d", minPort, maxPort] forKey:@"video_port_preference"]; else [self setObject:[NSString stringWithFormat:@"%d", minPort] forKey:@"video_port_preference"]; } [self setBool:[lm lpConfigBoolForKey:@"use_ipv6" withDefault:NO] forKey:@"use_ipv6"]; - LinphoneMediaEncryption menc = linphone_core_get_media_encryption(lc); + LinphoneMediaEncryption menc = linphone_core_get_media_encryption(LC); const char *val; switch (menc) { case LinphoneMediaEncryptionSRTP: @@ -341,9 +338,9 @@ [self setCString:val forKey:@"media_encryption_preference"]; [self setBool:[lm lpConfigBoolForKey:@"pushnotification_preference" withDefault:NO] forKey:@"pushnotification_preference"]; - [self setInteger:linphone_core_get_upload_bandwidth(lc) forKey:@"upload_bandwidth_preference"]; - [self setInteger:linphone_core_get_download_bandwidth(lc) forKey:@"download_bandwidth_preference"]; - [self setBool:linphone_core_adaptive_rate_control_enabled(lc) forKey:@"adaptive_rate_control_preference"]; + [self setInteger:linphone_core_get_upload_bandwidth(LC) forKey:@"upload_bandwidth_preference"]; + [self setInteger:linphone_core_get_download_bandwidth(LC) forKey:@"download_bandwidth_preference"]; + [self setBool:linphone_core_adaptive_rate_control_enabled(LC) forKey:@"adaptive_rate_control_preference"]; } // tunnel section @@ -364,7 +361,7 @@ // advanced section { - [self setBool:[lm lpConfigBoolForKey:@"debugenable_preference"] forKey:@"debugenable_preference"]; + [self setObject:[lm lpConfigStringForKey:@"debugenable_preference"] forKey:@"debugenable_preference"]; [self setBool:ANIMATED forKey:@"animations_preference"]; [self setBool:[lm lpConfigBoolForKey:@"backgroundmode_preference"] forKey:@"backgroundmode_preference"]; [self setBool:[lm lpConfigBoolForKey:@"start_at_boot_preference"] forKey:@"start_at_boot_preference"]; @@ -372,13 +369,13 @@ [self setBool:[lm lpConfigBoolForKey:@"show_msg_in_notif" withDefault:YES] forKey:@"show_msg_in_notif"]; [self setBool:[lm lpConfigBoolForKey:@"enable_first_login_view_preference"] forKey:@"enable_first_login_view_preference"]; - LinphoneAddress *parsed = linphone_core_get_primary_contact_parsed(lc); + LinphoneAddress *parsed = linphone_core_get_primary_contact_parsed(LC); if (parsed != NULL) { [self setCString:linphone_address_get_display_name(parsed) forKey:@"primary_displayname_preference"]; [self setCString:linphone_address_get_username(parsed) forKey:@"primary_username_preference"]; } linphone_address_destroy(parsed); - [self setCString:linphone_core_get_file_transfer_server(lc) forKey:@"file_transfer_server_url_preference"]; + [self setCString:linphone_core_get_file_transfer_server(LC) forKey:@"file_transfer_server_url_preference"]; } changedDict = [[NSMutableDictionary alloc] init]; @@ -400,7 +397,6 @@ - (void)synchronizeAccounts { LOGI(@"Account changed, synchronizing."); LinphoneManager *lm = LinphoneManager.instance; - LinphoneCore *lc = LC; LinphoneProxyConfig *proxyCfg = NULL; NSString *error = nil; @@ -415,18 +411,18 @@ LCSipTransports transportValue = {port_preference, port_preference, -1, -1}; // will also update the sip_*_port section of the config - if (linphone_core_set_sip_transports(lc, &transportValue)) { + if (linphone_core_set_sip_transports(LC, &transportValue)) { LOGE(@"cannot set transport"); } - port_preference = linphone_core_get_sip_port(lc); + port_preference = linphone_core_get_sip_port(LC); [self setInteger:port_preference forKey:@"port_preference"]; // Update back preference BOOL enable_ipv6 = [self boolForKey:@"use_ipv6"]; [lm lpConfigSetBool:enable_ipv6 forKey:@"use_ipv6" inSection:@"sip"]; - if (linphone_core_ipv6_enabled(lc) != enable_ipv6) { + if (linphone_core_ipv6_enabled(LC) != enable_ipv6) { LOGD(@"%@ IPV6", enable_ipv6 ? @"ENABLING" : @"DISABLING"); - linphone_core_enable_ipv6(lc, enable_ipv6); + linphone_core_enable_ipv6(LC, enable_ipv6); } // configure sip account @@ -482,7 +478,7 @@ char normalizedUserName[256]; LinphoneAddress *linphoneAddress = linphone_core_interpret_url(LC, "sip:user@domain.com"); - proxyCfg = ms_list_nth_data(linphone_core_get_proxy_config_list(lc), + proxyCfg = ms_list_nth_data(linphone_core_get_proxy_config_list(LC), [self integerForKey:@"current_proxy_config_preference"]); // if account was deleted, it is not present anymore if (proxyCfg == NULL) { @@ -494,7 +490,7 @@ linphone_address_set_username(linphoneAddress, normalizedUserName); linphone_address_set_domain(linphoneAddress, [domain UTF8String]); linphone_address_set_display_name(linphoneAddress, (displayName.length ? displayName.UTF8String : NULL)); - const char *identity = linphone_address_as_string_uri_only(linphoneAddress); + const char *identity = linphone_address_as_string(linphoneAddress); const char *password = [accountPassword UTF8String]; const char *ha1 = [accountHa1 UTF8String]; @@ -529,9 +525,9 @@ linphone_proxy_config_enable_avpf(proxyCfg, use_avpf); linphone_proxy_config_set_expires(proxyCfg, expire); if (is_default) { - linphone_core_set_default_proxy_config(lc, proxyCfg); - } else if (linphone_core_get_default_proxy_config(lc) == proxyCfg) { - linphone_core_set_default_proxy_config(lc, NULL); + linphone_core_set_default_proxy_config(LC, proxyCfg); + } else if (linphone_core_get_default_proxy_config(LC) == proxyCfg) { + linphone_core_set_default_proxy_config(LC, NULL); } LinphoneAuthInfo *proxyAi = (LinphoneAuthInfo *)linphone_proxy_config_find_auth_info(proxyCfg); @@ -542,7 +538,7 @@ // modify auth info only after finishing editting the proxy config, so that // UNREGISTER succeed if (proxyAi) { - linphone_core_remove_auth_info(lc, proxyAi); + linphone_core_remove_auth_info(LC, proxyAi); } LinphoneAddress *from = linphone_core_interpret_url(LC, identity); if (from) { @@ -551,7 +547,7 @@ linphone_address_get_username(from), userid_str, password ? password : NULL, password ? NULL : ha1, linphone_proxy_config_get_realm(proxyCfg), linphone_proxy_config_get_domain(proxyCfg)); linphone_address_destroy(from); - linphone_core_add_auth_info(lc, info); + linphone_core_add_auth_info(LC, info); linphone_auth_info_destroy(info); } @@ -577,20 +573,18 @@ } - (void)synchronizeCodecs:(const MSList *)codecs { - LinphoneCore *lc = LC; PayloadType *pt; const MSList *elem; for (elem = codecs; elem != NULL; elem = elem->next) { pt = (PayloadType *)elem->data; NSString *pref = [LinphoneManager getPreferenceForCodec:pt->mime_type withRate:pt->clock_rate]; - linphone_core_enable_payload_type(lc, pt, [self boolForKey:pref]); + linphone_core_enable_payload_type(LC, pt, [self boolForKey:pref]); } } - (BOOL)synchronize { LinphoneManager *lm = LinphoneManager.instance; - LinphoneCore *lc = LC; // root section { BOOL account_changed = NO; @@ -609,8 +603,8 @@ [self synchronizeAccounts]; bool enableVideo = [self boolForKey:@"enable_video_preference"]; - linphone_core_enable_video_capture(lc, enableVideo); - linphone_core_enable_video_display(lc, enableVideo); + linphone_core_enable_video_capture(LC, enableVideo); + linphone_core_enable_video_display(LC, enableVideo); bool enableAutoAnswer = [self boolForKey:@"enable_auto_answer_preference"]; [LinphoneManager.instance lpConfigSetBool:enableAutoAnswer forKey:@"auto_answer"]; @@ -618,13 +612,13 @@ // audio section { - [self synchronizeCodecs:linphone_core_get_audio_codecs(lc)]; + [self synchronizeCodecs:linphone_core_get_audio_codecs(LC)]; float playback_gain = [self floatForKey:@"playback_gain_preference"]; - linphone_core_set_playback_gain_db(lc, playback_gain); + linphone_core_set_playback_gain_db(LC, playback_gain); float mic_gain = [self floatForKey:@"microphone_gain_preference"]; - linphone_core_set_mic_gain_db(lc, mic_gain); + linphone_core_set_mic_gain_db(LC, mic_gain); [lm lpConfigSetInt:[self integerForKey:@"audio_codec_bitrate_limit_preference"] forKey:@"codec_bitrate_limit" @@ -642,24 +636,24 @@ if (!voice_processing) { au_device = @"AU: Audio Unit NoVoiceProc"; } - linphone_core_set_capture_device(lc, [au_device UTF8String]); - linphone_core_set_playback_device(lc, [au_device UTF8String]); + linphone_core_set_capture_device(LC, [au_device UTF8String]); + linphone_core_set_playback_device(LC, [au_device UTF8String]); } // video section { - [self synchronizeCodecs:linphone_core_get_video_codecs(lc)]; + [self synchronizeCodecs:linphone_core_get_video_codecs(LC)]; LinphoneVideoPolicy policy; policy.automatically_initiate = [self boolForKey:@"start_video_preference"]; policy.automatically_accept = [self boolForKey:@"accept_video_preference"]; - linphone_core_set_video_policy(lc, &policy); - linphone_core_enable_self_view(lc, [self boolForKey:@"self_video_preference"]); + linphone_core_set_video_policy(LC, &policy); + linphone_core_enable_self_view(LC, [self boolForKey:@"self_video_preference"]); BOOL preview_preference = IPAD && [self boolForKey:@"preview_preference"]; [lm lpConfigSetInt:preview_preference forKey:@"preview_preference"]; NSString *videoPreset = [self stringForKey:@"video_preset_preference"]; - linphone_core_set_video_preset(lc, [videoPreset UTF8String]); + linphone_core_set_video_preset(LC, [videoPreset UTF8String]); int bw; MSVideoSize vsize; switch ([self integerForKey:@"video_preferred_size_preference"]) { @@ -680,22 +674,22 @@ bw = 380; break; } - linphone_core_set_preferred_video_size(lc, vsize); + linphone_core_set_preferred_video_size(LC, vsize); if (![videoPreset isEqualToString:@"custom"]) { [self setInteger:0 forKey:@"video_preferred_fps_preference"]; [self setInteger:bw forKey:@"download_bandwidth_preference"]; } - linphone_core_set_preferred_framerate(lc, [self integerForKey:@"video_preferred_fps_preference"]); - linphone_core_set_download_bandwidth(lc, [self integerForKey:@"download_bandwidth_preference"]); - linphone_core_set_upload_bandwidth(lc, [self integerForKey:@"download_bandwidth_preference"]); + linphone_core_set_preferred_framerate(LC, [self integerForKey:@"video_preferred_fps_preference"]); + linphone_core_set_download_bandwidth(LC, [self integerForKey:@"download_bandwidth_preference"]); + linphone_core_set_upload_bandwidth(LC, [self integerForKey:@"download_bandwidth_preference"]); } // call section { - linphone_core_set_use_rfc2833_for_dtmf(lc, [self boolForKey:@"rfc_dtmf_preference"]); - linphone_core_set_use_info_for_dtmf(lc, [self boolForKey:@"sipinfo_dtmf_preference"]); - linphone_core_set_inc_timeout(lc, [self integerForKey:@"incoming_call_timeout_preference"]); - linphone_core_set_in_call_timeout(lc, [self integerForKey:@"in_call_timeout_preference"]); + linphone_core_set_use_rfc2833_for_dtmf(LC, [self boolForKey:@"rfc_dtmf_preference"]); + linphone_core_set_use_info_for_dtmf(LC, [self boolForKey:@"sipinfo_dtmf_preference"]); + linphone_core_set_inc_timeout(LC, [self integerForKey:@"incoming_call_timeout_preference"]); + linphone_core_set_in_call_timeout(LC, [self integerForKey:@"in_call_timeout_preference"]); [lm lpConfigSetString:[self stringForKey:@"voice_mail_uri_preference"] forKey:@"voice_mail_uri"]; [lm lpConfigSetBool:[self boolForKey:@"repeat_call_notification_preference"] forKey:@"repeat_call_notification"]; @@ -714,42 +708,42 @@ NSString *stun_server = [self stringForKey:@"stun_preference"]; if ([stun_server length] > 0) { - linphone_core_set_stun_server(lc, [stun_server UTF8String]); + linphone_core_set_stun_server(LC, [stun_server UTF8String]); BOOL ice_preference = [self boolForKey:@"ice_preference"]; if (ice_preference) { - linphone_core_set_firewall_policy(lc, LinphonePolicyUseIce); + linphone_core_set_firewall_policy(LC, LinphonePolicyUseIce); } else { - linphone_core_set_firewall_policy(lc, LinphonePolicyUseStun); + linphone_core_set_firewall_policy(LC, LinphonePolicyUseStun); } } else { - linphone_core_set_stun_server(lc, NULL); - linphone_core_set_firewall_policy(lc, LinphonePolicyNoFirewall); + linphone_core_set_stun_server(LC, NULL); + linphone_core_set_firewall_policy(LC, LinphonePolicyNoFirewall); } { NSString *audio_port_preference = [self stringForKey:@"audio_port_preference"]; int minPort, maxPort; [LinphoneCoreSettingsStore parsePortRange:audio_port_preference minPort:&minPort maxPort:&maxPort]; - linphone_core_set_audio_port_range(lc, minPort, maxPort); + linphone_core_set_audio_port_range(LC, minPort, maxPort); } { NSString *video_port_preference = [self stringForKey:@"video_port_preference"]; int minPort, maxPort; [LinphoneCoreSettingsStore parsePortRange:video_port_preference minPort:&minPort maxPort:&maxPort]; - linphone_core_set_video_port_range(lc, minPort, maxPort); + linphone_core_set_video_port_range(LC, minPort, maxPort); } NSString *menc = [self stringForKey:@"media_encryption_preference"]; if (menc && [menc compare:@"SRTP"] == NSOrderedSame) - linphone_core_set_media_encryption(lc, LinphoneMediaEncryptionSRTP); + linphone_core_set_media_encryption(LC, LinphoneMediaEncryptionSRTP); else if (menc && [menc compare:@"ZRTP"] == NSOrderedSame) - linphone_core_set_media_encryption(lc, LinphoneMediaEncryptionZRTP); + linphone_core_set_media_encryption(LC, LinphoneMediaEncryptionZRTP); else if (menc && [menc compare:@"DTLS"] == NSOrderedSame) - linphone_core_set_media_encryption(lc, LinphoneMediaEncryptionDTLS); + linphone_core_set_media_encryption(LC, LinphoneMediaEncryptionDTLS); else - linphone_core_set_media_encryption(lc, LinphoneMediaEncryptionNone); + linphone_core_set_media_encryption(LC, LinphoneMediaEncryptionNone); - linphone_core_enable_adaptive_rate_control(lc, [self boolForKey:@"adaptive_rate_control_preference"]); + linphone_core_enable_adaptive_rate_control(LC, [self boolForKey:@"adaptive_rate_control_preference"]); } // tunnel section @@ -810,12 +804,12 @@ NSString *displayname = [self stringForKey:@"primary_displayname_preference"]; NSString *username = [self stringForKey:@"primary_username_preference"]; - LinphoneAddress *parsed = linphone_core_get_primary_contact_parsed(lc); + LinphoneAddress *parsed = linphone_core_get_primary_contact_parsed(LC); if (parsed != NULL) { linphone_address_set_display_name(parsed, [displayname UTF8String]); linphone_address_set_username(parsed, [username UTF8String]); char *contact = linphone_address_as_string(parsed); - linphone_core_set_primary_contact(lc, contact); + linphone_core_set_primary_contact(LC, contact); ms_free(contact); linphone_address_destroy(parsed); } @@ -823,7 +817,7 @@ [lm lpConfigSetInt:[self integerForKey:@"account_mandatory_advanced_preference"] forKey:@"account_mandatory_advanced_preference"]; - linphone_core_set_file_transfer_server(lc, + linphone_core_set_file_transfer_server(LC, [[self stringForKey:@"file_transfer_server_url_preference"] UTF8String]); } @@ -837,23 +831,22 @@ } - (void)removeAccount { - LinphoneCore *lc = LC; - LinphoneProxyConfig *config = ms_list_nth_data(linphone_core_get_proxy_config_list(lc), + LinphoneProxyConfig *config = ms_list_nth_data(linphone_core_get_proxy_config_list(LC), [self integerForKey:@"current_proxy_config_preference"]); - BOOL isDefault = (linphone_core_get_default_proxy_config(lc) == config); + BOOL isDefault = (linphone_core_get_default_proxy_config(LC) == config); const LinphoneAuthInfo *ai = linphone_proxy_config_find_auth_info(config); - linphone_core_remove_proxy_config(lc, config); + linphone_core_remove_proxy_config(LC, config); if (ai) { - linphone_core_remove_auth_info(lc, ai); + linphone_core_remove_auth_info(LC, ai); } [self setInteger:-1 forKey:@"current_proxy_config_preference"]; if (isDefault) { // if we removed the default proxy config, set another one instead - if (linphone_core_get_proxy_config_list(lc) != NULL) { - linphone_core_set_default_proxy_index(lc, 0); + if (linphone_core_get_proxy_config_list(LC) != NULL) { + linphone_core_set_default_proxy_index(LC, 0); } } [self transformLinphoneCoreToKeys]; diff --git a/Classes/LinphoneManager.h b/Classes/LinphoneManager.h index 3387f31cf..fa9dac6c2 100644 --- a/Classes/LinphoneManager.h +++ b/Classes/LinphoneManager.h @@ -161,7 +161,7 @@ typedef struct _LinphoneManagerSounds { + (NSString*)cacheDirectory; - (void)acceptCall:(LinphoneCall *)call evenWithVideo:(BOOL)video; -- (BOOL)call:(const LinphoneAddress *)address transfer:(BOOL)transfer; +- (BOOL)call:(const LinphoneAddress *)address; +(id)getMessageAppDataForKey:(NSString*)key inMessage:(LinphoneChatMessage*)msg; +(void)setValueInMessageAppData:(id)value forKey:(NSString*)key inMessage:(LinphoneChatMessage*)msg; @@ -216,5 +216,6 @@ typedef struct _LinphoneManagerSounds { @property (readonly) LpConfig *configDb; @property(readonly) InAppProductsManager *iapManager; @property(strong, nonatomic) NSMutableArray *fileTransferDelegates; +@property BOOL nextCallIsTransfer; @end diff --git a/Classes/LinphoneManager.m b/Classes/LinphoneManager.m index 6c8053f2d..dd912378c 100644 --- a/Classes/LinphoneManager.m +++ b/Classes/LinphoneManager.m @@ -108,22 +108,6 @@ NSString *const kLinphoneInternalChatDBFilename = @"linphone_chats.db"; @implementation LinphoneManager @synthesize connectivity; -@synthesize network; -@synthesize frontCamId; -@synthesize backCamId; -@synthesize database; -@synthesize fastAddressBook; -@synthesize pushNotificationToken; -@synthesize sounds; -@synthesize logs; -@synthesize speakerEnabled; -@synthesize bluetoothAvailable; -@synthesize bluetoothEnabled; -@synthesize photoLibrary; -@synthesize tunnelMode; -@synthesize silentPushCompletion; -@synthesize wasRemoteProvisioned; -@synthesize configDb; struct codec_name_pref_table { const char *name; @@ -252,25 +236,25 @@ struct codec_name_pref_table codec_pref_table[] = {{"speex", 8000, "speex_8k_pre if ((self = [super init])) { AudioSessionInitialize(NULL, NULL, NULL, NULL); [NSNotificationCenter.defaultCenter addObserver:self - selector:@selector(audioRouteChangeListenerCallback2:) + selector:@selector(audioRouteChangeListenerCallback:) name:AVAudioSessionRouteChangeNotification object:nil]; NSString *path = [[NSBundle mainBundle] pathForResource:@"msg" ofType:@"wav"]; self.messagePlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL URLWithString:path] error:nil]; - sounds.vibrate = kSystemSoundID_Vibrate; + _sounds.vibrate = kSystemSoundID_Vibrate; - logs = [[NSMutableArray alloc] init]; - database = NULL; - speakerEnabled = FALSE; - bluetoothEnabled = FALSE; - tunnelMode = FALSE; + _logs = [[NSMutableArray alloc] init]; + _database = NULL; + _speakerEnabled = FALSE; + _bluetoothEnabled = FALSE; + _tunnelMode = FALSE; _fileTransferDelegates = [[NSMutableArray alloc] init]; pushCallIDs = [[NSMutableArray alloc] init]; - photoLibrary = [[ALAssetsLibrary alloc] init]; + _photoLibrary = [[ALAssetsLibrary alloc] init]; _isTesting = [LinphoneManager isRunningTests]; [self renameDefaultSettings]; @@ -280,9 +264,9 @@ struct codec_name_pref_table codec_pref_table[] = {{"speex", 8000, "speex_8k_pre // set default values for first boot if ([self lpConfigStringForKey:@"debugenable_preference"] == nil) { #ifdef DEBUG - [self lpConfigSetBool:TRUE forKey:@"debugenable_preference"]; + [self lpConfigSetInt:1 forKey:@"debugenable_preference"]; #else - [self lpConfigSetBool:FALSE forKey:@"debugenable_preference"]; + [self lpConfigSetInt:0 forKey:@"debugenable_preference"]; #endif } @@ -296,10 +280,10 @@ struct codec_name_pref_table codec_pref_table[] = {{"speex", 8000, "speex_8k_pre } - (void)silentPushFailed:(NSTimer *)timer { - if (silentPushCompletion) { - LOGI(@"silentPush failed, silentPushCompletion block: %p", silentPushCompletion); - silentPushCompletion(UIBackgroundFetchResultNoData); - silentPushCompletion = nil; + if (_silentPushCompletion) { + LOGI(@"silentPush failed, silentPushCompletion block: %p", _silentPushCompletion); + _silentPushCompletion(UIBackgroundFetchResultNoData); + _silentPushCompletion = nil; } } @@ -436,7 +420,7 @@ exit_dbmigration: - (void)migrateFromUserPrefs { static NSString *migration_flag = @"userpref_migration_done"; - if (configDb == nil) + if (_configDb == nil) return; if ([self lpConfigIntForKey:migration_flag withDefault:0]) { @@ -531,7 +515,7 @@ static void migrateWizardToAssistant(const char *entry, void *user_data) { } - (void)migrationFromVersion2To3 { - lp_config_for_each_entry(configDb, "wizard", migrateWizardToAssistant, (__bridge void *)(self)); + lp_config_for_each_entry(_configDb, "wizard", migrateWizardToAssistant, (__bridge void *)(self)); } #pragma mark - Linphone Core Functions @@ -573,10 +557,10 @@ static void dump_section(const char *section, void *data) { #pragma mark - Logs Functions handlers static void linphone_iphone_log_user_info(struct _LinphoneCore *lc, const char *message) { - linphone_iphone_log_handler(ORTP_MESSAGE, message, NULL); + linphone_iphone_log_handler(NULL, ORTP_MESSAGE, message, NULL); } static void linphone_iphone_log_user_warning(struct _LinphoneCore *lc, const char *message) { - linphone_iphone_log_handler(ORTP_WARNING, message, NULL); + linphone_iphone_log_handler(NULL, ORTP_WARNING, message, NULL); } #pragma mark - Display Status Functions @@ -615,13 +599,13 @@ static void linphone_iphone_display_status(struct _LinphoneCore *lc, const char linphone_call_set_user_data(call, (void *)CFBridgingRetain(data)); } - if (silentPushCompletion) { + if (_silentPushCompletion) { // we were woken up by a silent push. Call the completion handler with NEWDATA // so that the push is notified to the user - LOGI(@"onCall - handler %p", silentPushCompletion); - silentPushCompletion(UIBackgroundFetchResultNewData); - silentPushCompletion = nil; + LOGI(@"onCall - handler %p", _silentPushCompletion); + _silentPushCompletion(UIBackgroundFetchResultNewData); + _silentPushCompletion = nil; } const LinphoneAddress *addr = linphone_call_get_remote_address(call); @@ -708,10 +692,10 @@ static void linphone_iphone_display_status(struct _LinphoneCore *lc, const char if (linphone_core_get_calls_nb(theLinphoneCore) == 0) { [self setSpeakerEnabled:FALSE]; [self removeCTCallCenterCb]; - // disable this because I don't find anygood reason for it: bluetoothAvailable = FALSE; + // disable this because I don't find anygood reason for it: _bluetoothAvailable = FALSE; // furthermore it introduces a bug when calling multiple times since route may not be // reconfigured between cause leading to bluetooth being disabled while it should not - bluetoothEnabled = FALSE; + _bluetoothEnabled = FALSE; /*IOS specific*/ linphone_core_start_dtmf_stream(theLinphoneCore); } @@ -833,12 +817,8 @@ static void linphone_iphone_configuring_status_changed(LinphoneCore *lc, Linphon } - (void)configuringStateChangedNotificationHandler:(NSNotification *)notif { - if ((LinphoneConfiguringState)[[[notif userInfo] valueForKey:@"state"] integerValue] == - LinphoneConfiguringSuccessful) { - wasRemoteProvisioned = TRUE; - } else { - wasRemoteProvisioned = FALSE; - } + _wasRemoteProvisioned = ((LinphoneConfiguringState)[[[notif userInfo] valueForKey:@"state"] integerValue] == + LinphoneConfiguringSuccessful); } #pragma mark - Registration State Functions @@ -917,16 +897,20 @@ static void linphone_iphone_popup_password_request(LinphoneCore *lc, const char #pragma mark - Text Received Functions - (void)onMessageReceived:(LinphoneCore *)lc room:(LinphoneChatRoom *)room message:(LinphoneChatMessage *)msg { - if (silentPushCompletion) { + if (_silentPushCompletion) { // we were woken up by a silent push. Call the completion handler with NEWDATA // so that the push is notified to the user - LOGI(@"onMessageReceived - handler %p", silentPushCompletion); - silentPushCompletion(UIBackgroundFetchResultNewData); - silentPushCompletion = nil; + LOGI(@"onMessageReceived - handler %p", _silentPushCompletion); + _silentPushCompletion(UIBackgroundFetchResultNewData); + _silentPushCompletion = nil; } NSString *callID = [NSString stringWithUTF8String:linphone_chat_message_get_custom_header(msg, "Call-ID")]; const LinphoneAddress *remoteAddress = linphone_chat_message_get_from_address(msg); NSString *from = [FastAddressBook displayNameForAddress:remoteAddress]; + const char *chat = linphone_chat_message_get_text(msg); + if (chat == NULL) + chat = ""; + char *c_address = linphone_address_as_string_uri_only(remoteAddress); NSString *remote_uri = [NSString stringWithUTF8String:c_address]; @@ -1330,8 +1314,8 @@ static LinphoneCoreVTable linphonec_vtable = { _contactSipField = [self lpConfigStringForKey:@"contact_im_type_value" withDefault:@"SIP"]; - if (fastAddressBook == nil) { - fastAddressBook = [[FastAddressBook alloc] init]; + if (_fastAddressBook == nil) { + _fastAddressBook = [[FastAddressBook alloc] init]; } linphone_core_set_root_ca(theLinphoneCore, lRootCa); @@ -1354,16 +1338,16 @@ static LinphoneCoreVTable linphonec_vtable = { } /*DETECT cameras*/ - frontCamId = backCamId = nil; + _frontCamId = _backCamId = nil; char **camlist = (char **)linphone_core_get_video_devices(theLinphoneCore); for (char *cam = *camlist; *camlist != NULL; cam = *++camlist) { if (strcmp(FRONT_CAM_NAME, cam) == 0) { - frontCamId = cam; + _frontCamId = cam; // great set default cam to front linphone_core_set_video_device(theLinphoneCore, cam); } if (strcmp(BACK_CAM_NAME, cam) == 0) { - backCamId = cam; + _backCamId = cam; } } @@ -1439,8 +1423,7 @@ static BOOL libStarted = FALSE; LOGI(@"linphonecore is already created"); return; } - linphone_core_set_log_collection_path([[LinphoneManager cacheDirectory] UTF8String]); - [Log enableLogs:[self lpConfigBoolForKey:@"debugenable_preference"]]; + [Log enableLogs:[self lpConfigIntForKey:@"debugenable_preference"]]; connectivity = none; ms_init(); // Need to initialize mediastreamer2 before loading the plugins @@ -1453,29 +1436,27 @@ static BOOL libStarted = FALSE; libmsbcg729_init(ms_factory_get_fallback()); libmswebrtc_init(ms_factory_get_fallback()); - theLinphoneCore = linphone_core_new_with_config(&linphonec_vtable, configDb, (__bridge void *)(self)); + theLinphoneCore = linphone_core_new_with_config(&linphonec_vtable, _configDb, (__bridge void *)(self)); LOGI(@"Create linphonecore %p", theLinphoneCore); // Set audio assets NSString *ring = - ([LinphoneManager bundleFile:[NSString stringWithUTF8String:linphone_core_get_ringback(theLinphoneCore) ?: ""] - .lastPathComponent] + ([LinphoneManager + bundleFile:[NSString stringWithUTF8String:linphone_core_get_ring(theLinphoneCore) ?: ""].lastPathComponent] ?: [LinphoneManager bundleFile:@"notes_of_the_optimistic.caf"]) .lastPathComponent; NSString *ringback = - ([LinphoneManager - bundleFile:[NSString stringWithUTF8String:linphone_core_get_remote_ringback_tone(theLinphoneCore) ?: ""] - .lastPathComponent] + ([LinphoneManager bundleFile:[NSString stringWithUTF8String:linphone_core_get_ringback(theLinphoneCore) ?: ""] + .lastPathComponent] ?: [LinphoneManager bundleFile:@"ringback.wav"]) .lastPathComponent; NSString *hold = ([LinphoneManager bundleFile:[NSString stringWithUTF8String:linphone_core_get_play_file(theLinphoneCore) ?: ""] .lastPathComponent] - ?: [LinphoneManager bundleFile:@"hold.caf"]) + ?: [LinphoneManager bundleFile:@"hold.mkv"]) .lastPathComponent; - - linphone_core_set_ringback(theLinphoneCore, [LinphoneManager bundleFile:ring].UTF8String); - linphone_core_set_remote_ringback_tone(theLinphoneCore, [LinphoneManager bundleFile:ringback].UTF8String); + linphone_core_set_ring(theLinphoneCore, [LinphoneManager bundleFile:ring].UTF8String); + linphone_core_set_ringback(theLinphoneCore, [LinphoneManager bundleFile:ringback].UTF8String); linphone_core_set_play_file(theLinphoneCore, [LinphoneManager bundleFile:hold].UTF8String); /* set the CA file no matter what, since the remote provisioning could be hitting an HTTPS server */ @@ -1514,8 +1495,6 @@ static BOOL libStarted = FALSE; // just in case [self removeCTCallCenterCb]; - [NSNotificationCenter.defaultCenter removeObserver:self]; - if (theLinphoneCore != nil) { // just in case application terminate before linphone core initialization for (FileTransferDelegate *ftd in _fileTransferDelegates) { @@ -1541,6 +1520,7 @@ static BOOL libStarted = FALSE; proxyReachability = nil; } libStarted = FALSE; + [[NSNotificationCenter defaultCenter] removeObserver:self]; } - (void)resetLinphoneCore { @@ -1790,24 +1770,30 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) { factory = factoryIpad; } NSString *confiFileName = [LinphoneManager documentFile:@"linphonerc"]; - configDb = lp_config_new_with_factory([confiFileName UTF8String], [factory UTF8String]); + _configDb = lp_config_new_with_factory([confiFileName UTF8String], [factory UTF8String]); } #pragma mark - Audio route Functions - (bool)allowSpeaker { - bool notallow = false; + if (IPAD) + return true; + + bool allow = true; CFStringRef lNewRoute = CFSTR("Unknown"); UInt32 lNewRouteSize = sizeof(lNewRoute); OSStatus lStatus = AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &lNewRouteSize, &lNewRoute); if (!lStatus && lNewRouteSize > 0) { NSString *route = (__bridge NSString *)lNewRoute; - notallow = [route containsString:@"Heads"] || [route isEqualToString:@"Lineout"] || IPAD; + allow = ![route containsString:@"Heads"] && ![route isEqualToString:@"Lineout"]; CFRelease(lNewRoute); } - return !notallow; + return allow; } -- (void)audioRouteChangeListenerCallback2:(NSNotification *)notif { +- (void)audioRouteChangeListenerCallback:(NSNotification *)notif { + if (IPAD) + return; + // there is at least one bug when you disconnect an audio bluetooth headset // since we only get notification of route having changed, we cannot tell if that is due to: // -bluetooth headset disconnected or @@ -1815,7 +1801,7 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) { // the only thing we can assume is that when we lost a device, it must be a bluetooth one (strong hypothesis though) if ([[notif.userInfo valueForKey:AVAudioSessionRouteChangeReasonKey] integerValue] == AVAudioSessionRouteChangeReasonOldDeviceUnavailable) { - bluetoothAvailable = NO; + _bluetoothAvailable = NO; } CFStringRef newRoute = CFSTR("Unknown"); @@ -1826,15 +1812,15 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) { NSString *route = (__bridge NSString *)newRoute; LOGI(@"Current audio route is [%s]", [route UTF8String]); - speakerEnabled = [route isEqualToString:@"Speaker"] || [route isEqualToString:@"SpeakerAndMicrophone"]; - if (!IPAD && [route isEqualToString:@"HeadsetBT"] && !speakerEnabled) { - bluetoothAvailable = TRUE; - bluetoothEnabled = TRUE; + _speakerEnabled = [route isEqualToString:@"Speaker"] || [route isEqualToString:@"SpeakerAndMicrophone"]; + if ([route isEqualToString:@"HeadsetBT"] && !_speakerEnabled) { + _bluetoothAvailable = TRUE; + _bluetoothEnabled = TRUE; } else { - bluetoothEnabled = FALSE; + _bluetoothEnabled = FALSE; } - NSDictionary *dict = - [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:bluetoothAvailable], @"available", nil]; + NSDictionary *dict = [NSDictionary + dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:_bluetoothAvailable], @"available", nil]; [NSNotificationCenter.defaultCenter postNotificationName:kLinphoneBluetoothAvailabilityUpdate object:self userInfo:dict]; @@ -1844,17 +1830,17 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) { - (void)setSpeakerEnabled:(BOOL)enable { OSStatus ret; - speakerEnabled = enable; + _speakerEnabled = enable; UInt32 override = kAudioSessionUnspecifiedError; - if (!enable && bluetoothAvailable) { - UInt32 bluetoothInputOverride = bluetoothEnabled; + if (!enable && _bluetoothAvailable) { + UInt32 bluetoothInputOverride = _bluetoothEnabled; ret = AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryEnableBluetoothInput, sizeof(bluetoothInputOverride), &bluetoothInputOverride); // if setting bluetooth failed, it must be because the device is not available // anymore (disconnected), so deactivate bluetooth. if (ret != kAudioSessionNoError) { - bluetoothAvailable = bluetoothEnabled = FALSE; + _bluetoothAvailable = _bluetoothEnabled = FALSE; } } @@ -1862,7 +1848,7 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) { if (enable && [self allowSpeaker]) { override = kAudioSessionOverrideAudioRoute_Speaker; ret = AudioSessionSetProperty(kAudioSessionProperty_OverrideAudioRoute, sizeof(override), &override); - bluetoothEnabled = FALSE; + _bluetoothEnabled = FALSE; } else { override = kAudioSessionOverrideAudioRoute_None; ret = AudioSessionSetProperty(kAudioSessionProperty_OverrideAudioRoute, sizeof(override), &override); @@ -1875,14 +1861,10 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) { } - (void)setBluetoothEnabled:(BOOL)enable { - if (bluetoothAvailable) { + if (_bluetoothAvailable) { // The change of route will be done in setSpeakerEnabled - bluetoothEnabled = enable; - if (bluetoothEnabled) { - [self setSpeakerEnabled:FALSE]; - } else { - [self setSpeakerEnabled:speakerEnabled]; - } + _bluetoothEnabled = enable; + [self setSpeakerEnabled:!_bluetoothEnabled && _speakerEnabled]; } } @@ -1907,7 +1889,7 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) { linphone_core_accept_call_with_params(theLinphoneCore, call, lcallParams); } -- (BOOL)call:(const LinphoneAddress *)iaddr transfer:(BOOL)transfer { +- (BOOL)call:(const LinphoneAddress *)iaddr { // First verify that network is available, abort otherwise. if (!linphone_core_is_network_reachable(theLinphoneCore)) { UIAlertView *error = [[UIAlertView alloc] @@ -1967,9 +1949,11 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) { linphone_address_set_domain( addr, [[LinphoneManager.instance lpConfigStringForKey:@"domain" inSection:@"assistant"] UTF8String]); } - if (transfer) { + + if (LinphoneManager.instance.nextCallIsTransfer) { char *caddr = linphone_address_as_string(addr); linphone_core_transfer_call(theLinphoneCore, linphone_core_get_current_call(theLinphoneCore), caddr); + LinphoneManager.instance.nextCallIsTransfer = NO; ms_free(caddr); } else { LinphoneCall *call = linphone_core_invite_address_with_params(theLinphoneCore, addr, lcallParams); @@ -1995,16 +1979,11 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) { #pragma mark - Property Functions - (void)setPushNotificationToken:(NSData *)apushNotificationToken { - if (apushNotificationToken == pushNotificationToken) { + if (apushNotificationToken == _pushNotificationToken) { return; } - if (pushNotificationToken != nil) { - pushNotificationToken = nil; - } + _pushNotificationToken = apushNotificationToken; - if (apushNotificationToken != nil) { - pushNotificationToken = apushNotificationToken; - } LinphoneProxyConfig *cfg = linphone_core_get_default_proxy_config(theLinphoneCore); if (cfg) { linphone_proxy_config_edit(cfg); @@ -2014,7 +1993,7 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) { } - (void)configurePushTokenForProxyConfig:(LinphoneProxyConfig *)proxyCfg { - NSData *tokenData = pushNotificationToken; + NSData *tokenData = _pushNotificationToken; if (tokenData != nil && [self lpConfigBoolForKey:@"pushnotification_preference"]) { const unsigned char *tokenBuffer = [tokenData bytes]; NSMutableString *tokenString = [NSMutableString stringWithCapacity:[tokenData length] * 2]; @@ -2090,7 +2069,7 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) { } + (BOOL)copyFile:(NSString *)src destination:(NSString *)dst override:(BOOL)override { - NSFileManager *fileManager = [NSFileManager defaultManager]; + NSFileManager *fileManager = NSFileManager.defaultManager; NSError *error = nil; if ([fileManager fileExistsAtPath:src] == NO) { LOGE(@"Can't find \"%@\": %@", src, [error localizedDescription]); @@ -2119,7 +2098,7 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) { - (void)configureVbrCodecs { PayloadType *pt; int bitrate = lp_config_get_int( - configDb, "audio", "codec_bitrate_limit", + _configDb, "audio", "codec_bitrate_limit", kLinphoneAudioVbrCodecDefaultBitrate); /*default value is in linphonerc or linphonerc-factory*/ const MSList *audio_codecs = linphone_core_get_audio_codecs(theLinphoneCore); const MSList *codec = audio_codecs; @@ -2174,7 +2153,7 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) { - (void)lpConfigSetString:(NSString *)value forKey:(NSString *)key inSection:(NSString *)section { if (!key) return; - lp_config_set_string(configDb, [section UTF8String], [key UTF8String], value ? [value UTF8String] : NULL); + lp_config_set_string(_configDb, [section UTF8String], [key UTF8String], value ? [value UTF8String] : NULL); } - (NSString *)lpConfigStringForKey:(NSString *)key { return [self lpConfigStringForKey:key withDefault:nil]; @@ -2188,7 +2167,7 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) { - (NSString *)lpConfigStringForKey:(NSString *)key inSection:(NSString *)section withDefault:(NSString *)defaultValue { if (!key) return defaultValue; - const char *value = lp_config_get_string(configDb, [section UTF8String], [key UTF8String], NULL); + const char *value = lp_config_get_string(_configDb, [section UTF8String], [key UTF8String], NULL); return value ? [NSString stringWithUTF8String:value] : defaultValue; } @@ -2198,7 +2177,7 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) { - (void)lpConfigSetInt:(int)value forKey:(NSString *)key inSection:(NSString *)section { if (!key) return; - lp_config_set_int(configDb, [section UTF8String], [key UTF8String], (int)value); + lp_config_set_int(_configDb, [section UTF8String], [key UTF8String], (int)value); } - (int)lpConfigIntForKey:(NSString *)key { return [self lpConfigIntForKey:key withDefault:-1]; @@ -2212,7 +2191,7 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) { - (int)lpConfigIntForKey:(NSString *)key inSection:(NSString *)section withDefault:(int)defaultValue { if (!key) return defaultValue; - return lp_config_get_int(configDb, [section UTF8String], [key UTF8String], (int)defaultValue); + return lp_config_get_int(_configDb, [section UTF8String], [key UTF8String], (int)defaultValue); } - (void)lpConfigSetBool:(BOOL)value forKey:(NSString *)key { @@ -2295,8 +2274,8 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) { - (void)setTunnelMode:(TunnelMode)atunnelMode { LinphoneTunnel *tunnel = linphone_core_get_tunnel(theLinphoneCore); - tunnelMode = atunnelMode; - switch (tunnelMode) { + _tunnelMode = atunnelMode; + switch (_tunnelMode) { case tunnel_off: linphone_tunnel_enable(tunnel, false); break; diff --git a/Classes/LinphoneUI/Base.lproj/UIChatCell.xib b/Classes/LinphoneUI/Base.lproj/UIChatCell.xib index a9bdae0cc..fe2cac6ad 100644 --- a/Classes/LinphoneUI/Base.lproj/UIChatCell.xib +++ b/Classes/LinphoneUI/Base.lproj/UIChatCell.xib @@ -1,5 +1,5 @@ - + @@ -34,7 +34,7 @@