From 832844ea78fc7d276af347bbd1f17aaa0a48c6c0 Mon Sep 17 00:00:00 2001 From: Gautier Pelloux-Prayer Date: Thu, 15 Jan 2015 14:49:49 +0100 Subject: [PATCH 01/25] Unknown contact name should be localized Conflicts: Classes/LinphoneUI/UICallCell.m --- Classes/LinphoneManager.m | 4 +- Classes/LinphoneUI/UICallCell.m | 100 ++++++++++++++--------------- Classes/LinphoneUI/UIHistoryCell.m | 2 +- 3 files changed, 53 insertions(+), 53 deletions(-) diff --git a/Classes/LinphoneManager.m b/Classes/LinphoneManager.m index 007547a20..fba329fc4 100644 --- a/Classes/LinphoneManager.m +++ b/Classes/LinphoneManager.m @@ -637,7 +637,7 @@ static void linphone_iphone_display_status(struct _LinphoneCore * lc, const char } } if(address == nil) { - address = @"Unknown"; + address = NSLocalizedString(@"Unknown", nil); } if (state == LinphoneCallIncomingReceived) { @@ -897,7 +897,7 @@ static void linphone_iphone_registration_state(LinphoneCore *lc, LinphoneProxyCo } } if(address == nil) { - address = @"Unknown"; + address = NSLocalizedString(@"Unknown", nil); } // Create a new notification diff --git a/Classes/LinphoneUI/UICallCell.m b/Classes/LinphoneUI/UICallCell.m index eb857f8de..894cf1a27 100644 --- a/Classes/LinphoneUI/UICallCell.m +++ b/Classes/LinphoneUI/UICallCell.m @@ -4,16 +4,16 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ @@ -36,8 +36,8 @@ self->view = UICallCellOtherView_Avatar; self->call = acall; image = [[UIImage imageNamed:@"avatar_unknown.png"] retain]; - address = [@"Unknown" retain]; - [self update]; + address = [NSLocalizedString(@"Unknown",nil) retain]; + [self update]; } return self; } @@ -48,7 +48,7 @@ return; } const LinphoneAddress* addr = linphone_call_get_remote_address(call); - + if(addr != NULL) { BOOL useLinphoneAddress = true; // contact name @@ -85,7 +85,7 @@ - (void)dealloc { [address release]; [image release]; - + [super dealloc]; } @@ -145,7 +145,7 @@ NSArray *arrayOfViews = [[NSBundle mainBundle] loadNibNamed:@"UICallCell" owner:self options:nil]; - + if ([arrayOfViews count] >= 1) { //resize cell to match .nib size. It is needed when resized the cell to //correctly adapt its height too @@ -154,28 +154,28 @@ [self addSubview:sub]; } // Set selected+over background: IB lack ! - [pauseButton setImage:[UIImage imageNamed:@"call_state_pause_over.png"] + [pauseButton setImage:[UIImage imageNamed:@"call_state_pause_over.png"] forState:(UIControlStateHighlighted | UIControlStateSelected)]; - + self->currentCall = FALSE; - + self->detailsRightSwipeGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(doDetailsSwipe:)]; [detailsRightSwipeGestureRecognizer setDirection:UISwipeGestureRecognizerDirectionLeft]; [otherView addGestureRecognizer:detailsRightSwipeGestureRecognizer]; - + self->detailsRightSwipeGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(doDetailsSwipe:)]; [detailsRightSwipeGestureRecognizer setDirection:UISwipeGestureRecognizerDirectionRight]; [otherView addGestureRecognizer:detailsRightSwipeGestureRecognizer]; - + [self->avatarView setHidden:TRUE]; [self->audioStatsView setHidden:TRUE]; [self->videoStatsView setHidden:TRUE]; - + [UICallCell adaptSize:audioCodecHeaderLabel field:audioCodecLabel]; [UICallCell adaptSize:audioDownloadBandwidthHeaderLabel field:audioDownloadBandwidthLabel]; [UICallCell adaptSize:audioUploadBandwidthHeaderLabel field:audioUploadBandwidthLabel]; [UICallCell adaptSize:audioIceConnectivityHeaderLabel field:audioIceConnectivityLabel]; - + [UICallCell adaptSize:videoCodecHeaderLabel field:videoCodecLabel]; [UICallCell adaptSize:videoDownloadBandwidthHeaderLabel field:videoDownloadBandwidthLabel]; [UICallCell adaptSize:videoUploadBandwidthHeaderLabel field:videoUploadBandwidthLabel]; @@ -185,7 +185,7 @@ [LinphoneUtils adjustFontSize:self.audioStatsView mult:2.22]; [LinphoneUtils adjustFontSize:self.videoStatsView mult:2.22]; } - + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillEnterForeground:) name:UIApplicationWillEnterForegroundNotification @@ -198,23 +198,23 @@ [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillEnterForegroundNotification object:nil]; - - + + [headerBackgroundImage release]; [headerBackgroundHighlightImage release]; - + [addressLabel release]; [stateLabel release]; [stateImage release]; [avatarImage release]; [pauseButton release]; [removeButton release]; - + [headerView release]; [avatarView release]; - + [audioStatsView release]; - + [audioCodecLabel release]; [audioCodecHeaderLabel release]; [audioUploadBandwidthLabel release]; @@ -223,9 +223,9 @@ [audioDownloadBandwidthHeaderLabel release]; [audioIceConnectivityLabel release]; [audioIceConnectivityHeaderLabel release]; - + [videoStatsView release]; - + [videoCodecLabel release]; [videoCodecHeaderLabel release]; [videoUploadBandwidthLabel release]; @@ -234,11 +234,11 @@ [videoDownloadBandwidthHeaderLabel release]; [videoIceConnectivityLabel release]; [videoIceConnectivityHeaderLabel release]; - + [otherView release]; - + [data release]; - + [detailsLeftSwipeGestureRecognizer release]; [detailsRightSwipeGestureRecognizer release]; @@ -292,20 +292,20 @@ // CGRect labelFrame = [label frame]; CGRect fieldFrame = [field frame]; - + fieldFrame.origin.x -= labelFrame.size.width; - + // Compute firstName size CGSize contraints; contraints.height = [label frame].size.height; contraints.width = ([field frame].size.width + [field frame].origin.x) - [label frame].origin.x; CGSize firstNameSize = [[label text] sizeWithFont:[label font] constrainedToSize: contraints]; labelFrame.size.width = firstNameSize.width; - + // Compute lastName size & position fieldFrame.origin.x += labelFrame.size.width; fieldFrame.size.width = (contraints.width + [label frame].origin.x) - fieldFrame.origin.x; - + [label setFrame: labelFrame]; [field setFrame: fieldFrame]; } @@ -372,7 +372,7 @@ [target setAlpha:0.0f]; } - + #pragma mark - - (void)update { @@ -381,12 +381,12 @@ return; } LinphoneCall *call = data->call; - + [pauseButton setType:UIPauseButtonType_Call call:call]; - + [addressLabel setText:data.address]; [avatarImage setImage:data.image]; - + LinphoneCallState state = linphone_call_get_state(call); if(!conferenceCell) { if(state == LinphoneCallOutgoingRinging) { @@ -416,10 +416,10 @@ [removeButton setHidden:false]; [headerBackgroundImage setImage:[UIImage imageNamed:@"cell_conference.png"]]; } - + int duration = linphone_call_get_duration(call); [stateLabel setText:[NSString stringWithFormat:@"%02i:%02i", (duration/60), (duration%60), nil]]; - + if(!data->minimize) { CGRect frame = [self frame]; frame.size.height = [UICallCell getMaximizedHeight]; @@ -434,9 +434,9 @@ [self setFrame:frame]; [otherView setHidden:true]; } - + [self updateStats]; - + [self updateDetailsView]; } @@ -446,7 +446,7 @@ return; } LinphoneCall *call = data->call; - + const LinphoneCallParams *params = linphone_call_get_current_params(call); { const PayloadType* payload = linphone_call_params_get_used_audio_codec(params); @@ -466,7 +466,7 @@ [audioIceConnectivityLabel setText:@""]; } } - + { const PayloadType* payload = linphone_call_params_get_used_video_codec(params); if(payload != NULL) { @@ -474,7 +474,7 @@ } else { [videoCodecLabel setText:NSLocalizedString(@"No codec", nil)]; } - + const LinphoneCallStats *stats = linphone_call_get_video_stats(call); MSVideoSize sentSize = linphone_call_params_get_sent_video_size(params); @@ -520,7 +520,7 @@ - (void)selfUpdate { UITableView *parentTable = (UITableView *)self.superview; - + while( parentTable != nil && ![parentTable isKindOfClass:[UITableView class]] ) parentTable = (UITableView *)[parentTable superview]; if(parentTable != nil) { diff --git a/Classes/LinphoneUI/UIHistoryCell.m b/Classes/LinphoneUI/UIHistoryCell.m index e2e1ea941..2f9b9d82d 100644 --- a/Classes/LinphoneUI/UIHistoryCell.m +++ b/Classes/LinphoneUI/UIHistoryCell.m @@ -151,7 +151,7 @@ } } if(address == nil) { - address = @"Unknown"; + address = NSLocalizedString(@"Unknown", nil); } [addressLabel setText:address]; From 4c33973e00bb083409099a6b494a0d74b56b6115 Mon Sep 17 00:00:00 2001 From: Gautier Pelloux-Prayer Date: Thu, 15 Jan 2015 16:21:44 +0100 Subject: [PATCH 02/25] Fix UIRoundedImageView: when image is not squared, we should crop before doing radius treatment --- Classes/LinphoneUI/UIRoundedImageView.m | 13 +++++++++++-- linphone.xcodeproj/project.pbxproj | 6 ++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/Classes/LinphoneUI/UIRoundedImageView.m b/Classes/LinphoneUI/UIRoundedImageView.m index 100944f78..b3e7ce8a3 100644 --- a/Classes/LinphoneUI/UIRoundedImageView.m +++ b/Classes/LinphoneUI/UIRoundedImageView.m @@ -31,10 +31,19 @@ - (void)setRoundRadius:(BOOL)radius { CALayer *imageLayer = self.layer; + CGRect frame = imageLayer.frame; CGFloat height =self.frame.size.height; - CGFloat witdh = self.frame.size.width; - CGFloat roundRadius = height > witdh ? witdh / 2 : height / 2; + CGFloat width = self.frame.size.width; + CGFloat roundRadius = height > width ? width / 2 : height / 2; + if (height > width) { + frame.origin.y = height / 2 - width / 2; + frame.size.height = width; + } else { + frame.origin.x = width / 2 - height / 2; + frame.size.width = height; + } + [imageLayer setFrame:frame]; [imageLayer setCornerRadius:roundRadius]; [imageLayer setBorderWidth:0]; [imageLayer setMasksToBounds:YES]; diff --git a/linphone.xcodeproj/project.pbxproj b/linphone.xcodeproj/project.pbxproj index 49b6d1938..4d8a483e4 100755 --- a/linphone.xcodeproj/project.pbxproj +++ b/linphone.xcodeproj/project.pbxproj @@ -122,6 +122,7 @@ 639CEB061A1DF4F1004DE38F /* UIChatRoomCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 639CEB081A1DF4F1004DE38F /* UIChatRoomCell.xib */; }; 639CEB091A1DF4FA004DE38F /* UIChatCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 639CEB0B1A1DF4FA004DE38F /* UIChatCell.xib */; }; 63CD4B4F1A5AAC8C00B84282 /* DTAlertView.m in Sources */ = {isa = PBXBuildFile; fileRef = 63CD4B4E1A5AAC8C00B84282 /* DTAlertView.m */; }; + 63FB30351A680E73008CA393 /* UIRoundedImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 63FB30341A680E73008CA393 /* UIRoundedImageView.m */; }; 70571E1A13FABCB000CDD3C2 /* rootca.pem in Resources */ = {isa = PBXBuildFile; fileRef = 70571E1913FABCB000CDD3C2 /* rootca.pem */; }; 7066FC0C13E830E400EFC6DC /* libvpx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7066FC0B13E830E400EFC6DC /* libvpx.a */; }; 70E542F313E147E3002BA2C0 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 70E542F213E147E3002BA2C0 /* OpenGLES.framework */; }; @@ -976,6 +977,8 @@ 63CD4B4D1A5AAC8C00B84282 /* DTAlertView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DTAlertView.h; sourceTree = ""; }; 63CD4B4E1A5AAC8C00B84282 /* DTAlertView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DTAlertView.m; sourceTree = ""; }; 63EF7FDC1A24B5810017A416 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/AboutViewController.strings; sourceTree = ""; }; + 63FB30331A680E73008CA393 /* UIRoundedImageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIRoundedImageView.h; sourceTree = ""; }; + 63FB30341A680E73008CA393 /* UIRoundedImageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIRoundedImageView.m; sourceTree = ""; }; 70571E1913FABCB000CDD3C2 /* rootca.pem */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = rootca.pem; path = "liblinphone-sdk/apple-darwin/share/linphone/rootca.pem"; sourceTree = ""; }; 7066FC0B13E830E400EFC6DC /* libvpx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libvpx.a; path = "liblinphone-sdk/apple-darwin/lib/libvpx.a"; sourceTree = ""; }; 70E542F213E147E3002BA2C0 /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; }; @@ -2066,6 +2069,8 @@ 2214EBF212F86360002A5394 /* UIMicroButton.m */, D36FB2D31589EF7C0036F6F2 /* UIPauseButton.h */, D36FB2D41589EF7C0036F6F2 /* UIPauseButton.m */, + 63FB30331A680E73008CA393 /* UIRoundedImageView.h */, + 63FB30341A680E73008CA393 /* UIRoundedImageView.m */, 22968A5D12F875C600588287 /* UISpeakerButton.h */, 22968A5E12F875C600588287 /* UISpeakerButton.m */, D354981E1587716B000081D8 /* UIStateBar.h */, @@ -3792,6 +3797,7 @@ D378906515AC373B00BD776C /* ContactDetailsLabelViewController.m in Sources */, D3E8F68615ADE05B0065A226 /* UIContactDetailsFooter.m in Sources */, C90FAA7915AF54E6002091CB /* HistoryDetailsViewController.m in Sources */, + 63FB30351A680E73008CA393 /* UIRoundedImageView.m in Sources */, F066515517F9A02E0064280C /* UITransparentTVCell.m in Sources */, D3F9A9EE15AF277E0045320F /* UACellBackgroundView.m in Sources */, D35860D615B549B500513429 /* Utils.m in Sources */, From ab7c448a6011208abf68073ab87da52d481d6f9a Mon Sep 17 00:00:00 2001 From: Gautier Pelloux-Prayer Date: Fri, 16 Jan 2015 08:42:14 +0100 Subject: [PATCH 03/25] Fastbook should return only squared avatar image for everyone (by cropping non-squared one) --- Classes/LinphoneUI/UIContactDetailsHeader.m | 2 +- Classes/LinphoneUI/UIRoundedImageView.m | 14 ++------- Classes/Utils/FastAddressBook.m | 35 +++++++++++++++++++++ 3 files changed, 39 insertions(+), 12 deletions(-) diff --git a/Classes/LinphoneUI/UIContactDetailsHeader.m b/Classes/LinphoneUI/UIContactDetailsHeader.m index 090a4dd34..be4d05af9 100644 --- a/Classes/LinphoneUI/UIContactDetailsHeader.m +++ b/Classes/LinphoneUI/UIContactDetailsHeader.m @@ -123,7 +123,7 @@ // Avatar image { - UIImage *image = [FastAddressBook getContactImage:contact thumbnail:true]; + UIImage *image = [FastAddressBook getContactImage:contact thumbnail:false]; if(image == nil) { image = [UIImage imageNamed:@"avatar_unknown_small.png"]; } diff --git a/Classes/LinphoneUI/UIRoundedImageView.m b/Classes/LinphoneUI/UIRoundedImageView.m index b3e7ce8a3..983b9570c 100644 --- a/Classes/LinphoneUI/UIRoundedImageView.m +++ b/Classes/LinphoneUI/UIRoundedImageView.m @@ -29,21 +29,13 @@ [self setRoundRadius:rounded]; } +// warning: for non-squared image, this function will generate an ellipsoidal image, not a round image! - (void)setRoundRadius:(BOOL)radius { CALayer *imageLayer = self.layer; - CGRect frame = imageLayer.frame; - CGFloat height =self.frame.size.height; - CGFloat width = self.frame.size.width; + CGFloat height = frame.size.height; + CGFloat width = frame.size.width; CGFloat roundRadius = height > width ? width / 2 : height / 2; - if (height > width) { - frame.origin.y = height / 2 - width / 2; - frame.size.height = width; - } else { - frame.origin.x = width / 2 - height / 2; - frame.size.width = height; - } - [imageLayer setFrame:frame]; [imageLayer setCornerRadius:roundRadius]; [imageLayer setBorderWidth:0]; [imageLayer setMasksToBounds:YES]; diff --git a/Classes/Utils/FastAddressBook.m b/Classes/Utils/FastAddressBook.m index 0fe380de8..35fb6d6ec 100644 --- a/Classes/Utils/FastAddressBook.m +++ b/Classes/Utils/FastAddressBook.m @@ -36,6 +36,35 @@ static void sync_address_book (ABAddressBookRef addressBook, CFDictionaryRef inf return retString; } ++ (UIImage*)squareImageCrop:(UIImage*)image +{ + UIImage *ret = nil; + + // This calculates the crop area. + + float originalWidth = image.size.width; + float originalHeight = image.size.height; + + float edge = fminf(originalWidth, originalHeight); + + float posX = (originalWidth - edge) / 2.0f; + float posY = (originalHeight - edge) / 2.0f; + + + CGRect cropSquare = CGRectMake(posX, posY, + edge, edge); + + + CGImageRef imageRef = CGImageCreateWithImageInRect([image CGImage], cropSquare); + ret = [UIImage imageWithCGImage:imageRef + scale:image.scale + orientation:image.imageOrientation]; + + CGImageRelease(imageRef); + + return ret; +} + + (UIImage*)getContactImage:(ABRecordRef)contact thumbnail:(BOOL)thumbnail { UIImage* retImage = nil; if (contact && ABPersonHasImageData(contact)) { @@ -46,7 +75,13 @@ static void sync_address_book (ABAddressBookRef addressBook, CFDictionaryRef inf if(imgData != NULL) { CFRelease(imgData); } + + if (retImage != nil && retImage.size.width != retImage.size.height) { + [LinphoneLogger log:LinphoneLoggerLog format:@"Image is not square : cropping it."]; + return [self squareImageCrop:retImage]; + } } + return retImage; } From 57a9179a30afb27859c7f1821a230c6eddd35eac Mon Sep 17 00:00:00 2001 From: Gautier Pelloux-Prayer Date: Fri, 16 Jan 2015 08:47:23 +0100 Subject: [PATCH 04/25] Do not resize UIRoundendImageView actually because on rotation everything is broken --- Classes/LinphoneUI/UIRoundedImageView.m | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Classes/LinphoneUI/UIRoundedImageView.m b/Classes/LinphoneUI/UIRoundedImageView.m index 983b9570c..ed33f80e6 100644 --- a/Classes/LinphoneUI/UIRoundedImageView.m +++ b/Classes/LinphoneUI/UIRoundedImageView.m @@ -31,14 +31,14 @@ // warning: for non-squared image, this function will generate an ellipsoidal image, not a round image! - (void)setRoundRadius:(BOOL)radius { - CALayer *imageLayer = self.layer; - CGFloat height = frame.size.height; - CGFloat width = frame.size.width; - CGFloat roundRadius = height > width ? width / 2 : height / 2; + CALayer *imageLayer = self.layer; + CGFloat height = imageLayer.frame.size.height; + CGFloat width = imageLayer.frame.size.width; + CGFloat roundRadius = height > width ? width / 2 : height / 2; - [imageLayer setCornerRadius:roundRadius]; - [imageLayer setBorderWidth:0]; - [imageLayer setMasksToBounds:YES]; + [imageLayer setCornerRadius:roundRadius]; + [imageLayer setBorderWidth:0]; + [imageLayer setMasksToBounds:YES]; } From 49188892f5a391586b334393177a1f2d29fa3f3d Mon Sep 17 00:00:00 2001 From: Guillaume BIENKOWSKI Date: Thu, 15 Jan 2015 11:44:56 +0100 Subject: [PATCH 05/25] Fir #2009: Update linphone for SAL fix and use linphone_core_interpret_url() instead of linphone_address_new(). This simplifies the -call: method. --- Classes/LinphoneManager.m | 30 ++++++++---------------------- submodules/linphone | 2 +- 2 files changed, 9 insertions(+), 23 deletions(-) diff --git a/Classes/LinphoneManager.m b/Classes/LinphoneManager.m index fba329fc4..4677b742e 100644 --- a/Classes/LinphoneManager.m +++ b/Classes/LinphoneManager.m @@ -1863,8 +1863,6 @@ static void audioRouteChangeListenerCallback ( BOOL addressIsASCII = [address canBeConvertedToEncoding:[NSString defaultCStringEncoding]]; if ([address length] == 0) return; //just return - - if( !addressIsASCII ){ UIAlertView* error = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Invalid SIP address",nil) message:NSLocalizedString(@"The address should only contain ASCII data",nil) @@ -1874,9 +1872,11 @@ static void audioRouteChangeListenerCallback ( [error show]; [error release]; - } else if ([address hasPrefix:@"sip:"] || [address hasPrefix:@"sips:"]) { + } + LinphoneAddress* linphoneAddress = linphone_core_interpret_url(theLinphoneCore, [address cStringUsingEncoding:[NSString defaultCStringEncoding]]); + + if (linphoneAddress) { - LinphoneAddress* linphoneAddress = linphone_address_new([address cStringUsingEncoding:[NSString defaultCStringEncoding]]); if(displayName!=nil) { linphone_address_set_display_name(linphoneAddress,[displayName cStringUsingEncoding:[NSString defaultCStringEncoding]]); } @@ -1889,7 +1889,7 @@ static void audioRouteChangeListenerCallback ( } linphone_address_destroy(linphoneAddress); - } else if (proxyCfg==nil){ + } else { UIAlertView* error = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Invalid SIP address",nil) message:NSLocalizedString(@"Either configure a SIP proxy server from settings prior to place a call or use a valid SIP address (I.E sip:john@example.net)",nil) @@ -1899,23 +1899,9 @@ static void audioRouteChangeListenerCallback ( [error show]; [error release]; - } else { - char normalizedUserName[256]; - LinphoneAddress* linphoneAddress = linphone_address_new(linphone_core_get_identity(theLinphoneCore)); - linphone_proxy_config_normalize_number(proxyCfg,[address cStringUsingEncoding:[NSString defaultCStringEncoding]],normalizedUserName,sizeof(normalizedUserName)); - linphone_address_set_username(linphoneAddress, normalizedUserName); - if(displayName!=nil) { - linphone_address_set_display_name(linphoneAddress, [displayName cStringUsingEncoding:[NSString defaultCStringEncoding]]); - } - if ([[LinphoneManager instance] lpConfigBoolForKey:@"override_domain_with_default_one"]) - linphone_address_set_domain(linphoneAddress, [[[LinphoneManager instance] lpConfigStringForKey:@"domain" forSection:@"wizard"] cStringUsingEncoding:[NSString defaultCStringEncoding]]); - if(transfer) { - linphone_core_transfer_call(theLinphoneCore, linphone_core_get_current_call(theLinphoneCore), linphone_address_as_string_uri_only(linphoneAddress)); - } else { - call=linphone_core_invite_address_with_params(theLinphoneCore, linphoneAddress, lcallParams); - } - linphone_address_destroy(linphoneAddress); - } + } + + if (call) { // The LinphoneCallAppData object should be set on call creation with callback // - (void)onCall:StateChanged:withMessage:. If not, we are in big trouble and expect it to crash diff --git a/submodules/linphone b/submodules/linphone index c0870da1e..f2a4cb60d 160000 --- a/submodules/linphone +++ b/submodules/linphone @@ -1 +1 @@ -Subproject commit c0870da1e7e360dadc511bc404f7f5a24f56e4f8 +Subproject commit f2a4cb60d2928f96b5300011aa8398d14c8e22a2 From 2eb545859215d4c46d32db2abf2094ede08d0d7b Mon Sep 17 00:00:00 2001 From: Guillaume BIENKOWSKI Date: Thu, 15 Jan 2015 12:35:13 +0100 Subject: [PATCH 06/25] Fix #2008: correctly handle sip addresses --- Classes/LinphoneAppDelegate.m | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Classes/LinphoneAppDelegate.m b/Classes/LinphoneAppDelegate.m index c13700ed2..798060d5a 100644 --- a/Classes/LinphoneAppDelegate.m +++ b/Classes/LinphoneAppDelegate.m @@ -245,10 +245,12 @@ [confirmation release]; } else { if([[url scheme] isEqualToString:@"sip"]) { - // Go to Dialer view - DialerViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[DialerViewController compositeViewDescription]], DialerViewController); + // remove "sip://" from the URI, and do it correctly by taking resourceSpecifier and removing leading and trailing "/" + NSString* sipUri = [[url resourceSpecifier] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"/"]]; + + DialerViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[DialerViewController compositeViewDescription]], DialerViewController); if(controller != nil) { - [controller setAddress:[url absoluteString]]; + [controller setAddress:sipUri]; } } } From a6f850a8b707eb52b1ae412c0e00cab18f72757c Mon Sep 17 00:00:00 2001 From: Guillaume BIENKOWSKI Date: Thu, 15 Jan 2015 12:49:54 +0100 Subject: [PATCH 07/25] Remove rotation preferences: we now use the iOS feature of screen rotation lock. Fixes #2002 --- Classes/LinphoneCoreSettingsStore.m | 4 - .../LinphoneUI/UICompositeViewController.m | 91 ++++++------------- Resources/linphonerc | 1 - Resources/linphonerc~ipad | 1 - Settings/InAppSettings.bundle/Advanced.plist | 22 ----- 5 files changed, 30 insertions(+), 89 deletions(-) diff --git a/Classes/LinphoneCoreSettingsStore.m b/Classes/LinphoneCoreSettingsStore.m index 47c0b79fb..2327a34d0 100644 --- a/Classes/LinphoneCoreSettingsStore.m +++ b/Classes/LinphoneCoreSettingsStore.m @@ -204,7 +204,6 @@ extern void linphone_iphone_log_handler(int lev, const char *fmt, va_list args); } [self setString:val forKey:@"media_encryption_preference"]; } - [self setString: lp_config_get_string(conf, LINPHONERC_APPLICATION_KEY, "rotation_preference", "auto") forKey:@"rotation_preference"]; [self setBool: lp_config_get_int(conf, LINPHONERC_APPLICATION_KEY, "edge_opt_preference", 0) forKey:@"edge_opt_preference"]; [self setBool: lp_config_get_int(conf, LINPHONERC_APPLICATION_KEY, "enable_first_login_view_preference", 0) forKey:@"enable_first_login_view_preference"]; [self setBool: lp_config_get_int(conf, LINPHONERC_APPLICATION_KEY, "debugenable_preference", 0) forKey:@"debugenable_preference"]; @@ -684,9 +683,6 @@ extern void linphone_iphone_log_handler(int lev, const char *fmt, va_list args); BOOL edgeOpt = [self boolForKey:@"edge_opt_preference"]; lp_config_set_int(config, LINPHONERC_APPLICATION_KEY, "edge_opt_preference", edgeOpt); - NSString *landscape = [self stringForKey:@"rotation_preference"]; - lp_config_set_string(config, LINPHONERC_APPLICATION_KEY, "rotation_preference", [landscape UTF8String]); - BOOL debugmode = [self boolForKey:@"debugenable_preference"]; lp_config_set_int(config, LINPHONERC_APPLICATION_KEY, "debugenable_preference", debugmode); [[LinphoneManager instance] setLogsEnabled:debugmode]; diff --git a/Classes/LinphoneUI/UICompositeViewController.m b/Classes/LinphoneUI/UICompositeViewController.m index 629370009..f5e4126f5 100644 --- a/Classes/LinphoneUI/UICompositeViewController.m +++ b/Classes/LinphoneUI/UICompositeViewController.m @@ -372,76 +372,45 @@ [controller view]; // Load the view } } - return controller; + return controller; } - (UIInterfaceOrientation)getCorrectInterfaceOrientation:(UIDeviceOrientation)deviceOrientation { - if(currentViewDescription != nil) { - // If unknown return status bar orientation - if(deviceOrientation == UIDeviceOrientationUnknown && currentOrientation == UIDeviceOrientationUnknown) { - return [UIApplication sharedApplication].statusBarOrientation; - } - - NSString* rotationPreference = [[LinphoneManager instance] lpConfigStringForKey:@"rotation_preference"]; - if([rotationPreference isEqualToString:@"auto"]) { - // Don't rotate in UIDeviceOrientationFaceUp UIDeviceOrientationFaceDown - if(!UIDeviceOrientationIsPortrait(deviceOrientation) && !UIDeviceOrientationIsLandscape(deviceOrientation)) { - if(currentOrientation == UIDeviceOrientationUnknown) { - return [UIApplication sharedApplication].statusBarOrientation; - } - deviceOrientation = (UIDeviceOrientation)currentOrientation; - } - if (UIDeviceOrientationIsPortrait(deviceOrientation)) { - if ([currentViewDescription portraitMode]) { - return (UIInterfaceOrientation)deviceOrientation; - } else { - return UIInterfaceOrientationLandscapeLeft; - } - } - if (UIDeviceOrientationIsLandscape(deviceOrientation)) { - if ([currentViewDescription landscapeMode]) { - return (UIInterfaceOrientation)deviceOrientation; - } else { - return UIInterfaceOrientationPortrait; - } - } - } else if([rotationPreference isEqualToString:@"portrait"]) { - if ([currentViewDescription portraitMode]) { - if (UIDeviceOrientationIsPortrait(deviceOrientation)) { - return (UIInterfaceOrientation)deviceOrientation; - } else { - if(UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation)) { - return [UIApplication sharedApplication].statusBarOrientation; - } else { - return UIInterfaceOrientationPortrait; - } - } - } else { - return UIInterfaceOrientationLandscapeLeft; - } - } else if([rotationPreference isEqualToString:@"landscape"]) { - if ([currentViewDescription landscapeMode]) { - if (UIDeviceOrientationIsLandscape(deviceOrientation)) { - return (UIInterfaceOrientation)deviceOrientation; - } else { - if(UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation)) { - return [UIApplication sharedApplication].statusBarOrientation; - } else { - return UIInterfaceOrientationLandscapeLeft; - } - } - } else { - return UIInterfaceOrientationPortrait; - } - } - } + if(currentViewDescription != nil) { + // If unknown return status bar orientation + if(deviceOrientation == UIDeviceOrientationUnknown && currentOrientation == UIDeviceOrientationUnknown) { + return [UIApplication sharedApplication].statusBarOrientation; + } + + // Don't rotate in UIDeviceOrientationFaceUp UIDeviceOrientationFaceDown + if(!UIDeviceOrientationIsPortrait(deviceOrientation) && !UIDeviceOrientationIsLandscape(deviceOrientation)) { + if(currentOrientation == UIDeviceOrientationUnknown) { + return [UIApplication sharedApplication].statusBarOrientation; + } + deviceOrientation = (UIDeviceOrientation)currentOrientation; + } + if (UIDeviceOrientationIsPortrait(deviceOrientation)) { + if ([currentViewDescription portraitMode]) { + return (UIInterfaceOrientation)deviceOrientation; + } else { + return UIInterfaceOrientationLandscapeLeft; + } + } + if (UIDeviceOrientationIsLandscape(deviceOrientation)) { + if ([currentViewDescription landscapeMode]) { + return (UIInterfaceOrientation)deviceOrientation; + } else { + return UIInterfaceOrientationPortrait; + } + } + } return UIInterfaceOrientationPortrait; } #define IPHONE_STATUSBAR_HEIGHT 20 - (void)update: (UICompositeViewDescription*) description tabBar:(NSNumber*)tabBar stateBar:(NSNumber*)stateBar fullscreen:(NSNumber*)fullscreen { - + UIViewController *oldContentViewController = self.contentViewController; UIViewController *oldStateBarViewController = self.stateBarViewController; UIViewController *oldTabBarViewController = self.tabBarViewController; diff --git a/Resources/linphonerc b/Resources/linphonerc index c8122e63d..6812b6238 100644 --- a/Resources/linphonerc +++ b/Resources/linphonerc @@ -30,7 +30,6 @@ capture_dev_id=AU: Audio Unit Receiver eq_active=0 [app] -rotation_preference=auto animations_preference=1 edge_opt_preference=0 use_system_contacts=0 diff --git a/Resources/linphonerc~ipad b/Resources/linphonerc~ipad index 69042e73a..c19045ae8 100644 --- a/Resources/linphonerc~ipad +++ b/Resources/linphonerc~ipad @@ -30,7 +30,6 @@ capture_dev_id=AU: Audio Unit Receiver eq_active=0 [app] -rotation_preference=auto animations_preference=1 edge_opt_preference=0 use_system_contacts=0 diff --git a/Settings/InAppSettings.bundle/Advanced.plist b/Settings/InAppSettings.bundle/Advanced.plist index 9b8e9831a..80632bbb7 100644 --- a/Settings/InAppSettings.bundle/Advanced.plist +++ b/Settings/InAppSettings.bundle/Advanced.plist @@ -52,28 +52,6 @@ Type PSToggleSwitchSpecifier - - DefaultValue - auto - Key - rotation_preference - Title - Rotation - Titles - - Automatic - Portrait - Landscape - - Type - PSMultiValueSpecifier - Values - - auto - portrait - landscape - - DefaultValue From 10cfee9ce2c17122e1ad97522b327da02927bae5 Mon Sep 17 00:00:00 2001 From: Guillaume BIENKOWSKI Date: Thu, 15 Jan 2015 12:56:49 +0100 Subject: [PATCH 08/25] Don't ask the user to validate the Wizard launch if no proxy is configured. Fixes #2005 --- Classes/SettingsViewController.m | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/Classes/SettingsViewController.m b/Classes/SettingsViewController.m index c860ee322..e1a53e5ee 100644 --- a/Classes/SettingsViewController.m +++ b/Classes/SettingsViewController.m @@ -672,6 +672,13 @@ static UICompositeViewDescription *compositeDescription = nil; return hiddenKeys; } +- (void)goToWizard { + WizardViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[WizardViewController compositeViewDescription]], WizardViewController); + if(controller != nil) { + [controller reset]; + } +} + #pragma mark - IASKSettingsDelegate Functions - (void)settingsViewControllerDidEnd:(IASKAppSettingsViewController *)sender { @@ -694,6 +701,12 @@ static UICompositeViewDescription *compositeDescription = nil; } #endif if([key isEqual:@"wizard_button"]) { + LinphoneProxyConfig* proxy = NULL; + linphone_core_get_default_proxy([LinphoneManager getLc], &proxy); + if (proxy == NULL ) { + [self goToWizard]; + return; + } UIAlertView* alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Warning",nil) message:NSLocalizedString(@"Launching the Wizard will delete any existing proxy config.\nAre you sure to want it?",nil) delegate:self @@ -736,12 +749,8 @@ static UICompositeViewDescription *compositeDescription = nil; #pragma mark - UIAlertView delegate - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { - if( buttonIndex != 1 ) return; - - WizardViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[WizardViewController compositeViewDescription]], WizardViewController); - if(controller != nil) { - [controller reset]; - } + if( buttonIndex != 1 ) return; /* cancel */ + else [self goToWizard]; } #pragma mark - Mail composer for send log From 0f6f089e36c451040799ea47816694c8b4ce31da Mon Sep 17 00:00:00 2001 From: Guillaume BIENKOWSKI Date: Thu, 15 Jan 2015 16:20:56 +0100 Subject: [PATCH 09/25] Fix #1996: don't ignore push notifications, and use the msg call-id to decide whether it should be inhibited. --- Classes/LinphoneAppDelegate.m | 33 +++++++++++-------------- Classes/LinphoneManager.h | 6 ++--- Classes/LinphoneManager.m | 46 ++++++++++++++++++----------------- Classes/PhoneMainView.m | 35 +++++++++++++++++--------- 4 files changed, 64 insertions(+), 56 deletions(-) diff --git a/Classes/LinphoneAppDelegate.m b/Classes/LinphoneAppDelegate.m index 798060d5a..8f9d523d3 100644 --- a/Classes/LinphoneAppDelegate.m +++ b/Classes/LinphoneAppDelegate.m @@ -267,11 +267,7 @@ } - (void)processRemoteNotification:(NSDictionary*)userInfo{ - if ([LinphoneManager instance].pushNotificationToken==Nil){ - [LinphoneLogger log:LinphoneLoggerLog format:@"Ignoring push notification we did not subscribed."]; - return; - } - + NSDictionary *aps = [userInfo objectForKey:@"aps"]; if(aps != nil) { @@ -286,18 +282,22 @@ [LinphoneManager instance].connectivity=none; /*force connectivity to be discovered again*/ [[LinphoneManager instance] refreshRegisters]; if(loc_key != nil) { - if([loc_key isEqualToString:@"IM_MSG"]) { - [[PhoneMainView instance] addInhibitedEvent:kLinphoneTextReceived]; + + NSString* callId = [userInfo objectForKey:@"call-id"]; + if( callId != nil ){ + [[LinphoneManager instance] addPushCallId:callId]; + } else { + [LinphoneLogger log:LinphoneLoggerError format:@"PushNotification: does not have call-id yet, fix it !"]; + } + + if( [loc_key isEqualToString:@"IM_MSG"] ) { + [[PhoneMainView instance] changeCurrentView:[ChatViewController compositeViewDescription]]; - } else if([loc_key isEqualToString:@"IC_MSG"]) { - //it's a call - NSString *callid=[userInfo objectForKey:@"call-id"]; - if (callid) - [[LinphoneManager instance] enableAutoAnswerForCallId:callid]; - else - [LinphoneLogger log:LinphoneLoggerError format:@"PushNotification: does not have call-id yet, fix it !"]; + + } else if( [loc_key isEqualToString:@"IC_MSG"] ) { [self fixRing]; + } } } @@ -367,11 +367,6 @@ { Linphone_log(@"%@ : %@", NSStringFromSelector(_cmd), userInfo); LinphoneManager* lm = [LinphoneManager instance]; - - if (lm.pushNotificationToken==Nil){ - [LinphoneLogger log:LinphoneLoggerLog format:@"Ignoring push notification we did not subscribed."]; - return; - } // save the completion handler for later execution. // 2 outcomes: diff --git a/Classes/LinphoneManager.h b/Classes/LinphoneManager.h index f0545b9c6..99adcdb7d 100644 --- a/Classes/LinphoneManager.h +++ b/Classes/LinphoneManager.h @@ -107,7 +107,7 @@ typedef struct _LinphoneManagerSounds { @private NSTimer* mIterateTimer; - NSMutableArray* pendindCallIdFromRemoteNotif; + NSMutableArray* pushCallIDs; Connectivity connectivity; UIBackgroundTaskIdentifier pausedCallBgTask; UIBackgroundTaskIdentifier incallBgTask; @@ -137,9 +137,9 @@ typedef struct _LinphoneManagerSounds { - (BOOL)resignActive; - (void)becomeActive; - (BOOL)enterBackgroundMode; -- (void)enableAutoAnswerForCallId:(NSString*) callid; +- (void)addPushCallId:(NSString*) callid; - (void)configurePushTokenForProxyConfig: (LinphoneProxyConfig*)cfg; -- (BOOL)shouldAutoAcceptCallForCallId:(NSString*) callId; +- (BOOL)popPushCallID:(NSString*) callId; - (void)acceptCallForCallId:(NSString*)callid; - (void)cancelLocalNotifTimerForCallId:(NSString*)callid; diff --git a/Classes/LinphoneManager.m b/Classes/LinphoneManager.m index 4677b742e..3a08d0683 100644 --- a/Classes/LinphoneManager.m +++ b/Classes/LinphoneManager.m @@ -276,7 +276,7 @@ struct codec_name_pref_table codec_pref_table[]={ bluetoothEnabled = FALSE; tunnelMode = FALSE; [self copyDefaultSettings]; - pendindCallIdFromRemoteNotif = [[NSMutableArray alloc] init ]; + pushCallIDs = [[NSMutableArray alloc] init ]; photoLibrary = [[ALAssetsLibrary alloc] init]; NSString* factoryConfig = [LinphoneManager bundleFile:[LinphoneManager runningOnIpad]?@"linphonerc-factory~ipad":@"linphonerc-factory"]; @@ -311,7 +311,7 @@ struct codec_name_pref_table codec_pref_table[]={ [photoLibrary release]; - [pendindCallIdFromRemoteNotif release]; + [pushCallIDs release]; [super dealloc]; } @@ -663,7 +663,7 @@ static void linphone_iphone_display_status(struct _LinphoneCore * lc, const char LinphoneCallLog* callLog=linphone_call_get_call_log(call); NSString* callId=[NSString stringWithUTF8String:linphone_call_log_get_call_id(callLog)]; - if (![[LinphoneManager instance] shouldAutoAcceptCallForCallId:callId]){ + if (![[LinphoneManager instance] popPushCallID:callId]){ // case where a remote notification is not already received // Create a new local notification data->notification = [[UILocalNotification alloc] init]; @@ -878,14 +878,16 @@ static void linphone_iphone_registration_state(LinphoneCore *lc, LinphoneProxyCo silentPushCompletion(UIBackgroundFetchResultNewData); silentPushCompletion = nil; } + const LinphoneAddress* remoteAddress = linphone_chat_message_get_from_address(msg); + char* c_address = linphone_address_as_string_uri_only(remoteAddress); + NSString* address = [NSString stringWithUTF8String:c_address]; + const char* call_id = linphone_chat_message_get_custom_header(msg, "Call-ID"); + NSString* callID = [NSString stringWithUTF8String:call_id]; + + ms_free(c_address); if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground) { - const LinphoneAddress* remoteAddress = linphone_chat_message_get_from_address(msg); - char* c_address = linphone_address_as_string_uri_only(remoteAddress); - NSString* address = [NSString stringWithUTF8String:c_address]; - NSString* from_address = [address copy]; - ABRecordRef contact = [fastAddressBook getContact:address]; if(contact) { address = [FastAddressBook getContactDisplayName:contact]; @@ -910,18 +912,18 @@ static void linphone_iphone_registration_state(LinphoneCore *lc, LinphoneProxyCo notif.alertBody = [NSString stringWithFormat:NSLocalizedString(@"IM_MSG",nil), address]; notif.alertAction = NSLocalizedString(@"Show", nil); notif.soundName = @"msg.caf"; - notif.userInfo = @{@"from":from_address}; - + notif.userInfo = @{@"from":address, @"call-id":callID}; [[UIApplication sharedApplication] presentLocalNotificationNow:notif]; } - [from_address release]; } // Post event NSDictionary* dict = @{@"room" :[NSValue valueWithPointer:room], - @"from_address":[NSValue valueWithPointer:linphone_chat_message_get_from(msg)], - @"message" :[NSValue valueWithPointer:msg]}; + @"from_address":[NSValue valueWithPointer:linphone_chat_message_get_from_address(msg)], + @"message" :[NSValue valueWithPointer:msg], + @"call-id" : callID}; + [[NSNotificationCenter defaultCenter] postNotificationName:kLinphoneTextReceived object:self userInfo:dict]; } @@ -1532,23 +1534,23 @@ static int comp_call_id(const LinphoneCall* call , const char *callid) { }; } -- (void)enableAutoAnswerForCallId:(NSString*) callid { - //first, make sure this callid is not already involved in a call +- (void)addPushCallId:(NSString*) callid { + //first, make sure this callid is not already involved in a call MSList* calls = (MSList*)linphone_core_get_calls(theLinphoneCore); if (ms_list_find_custom(calls, (MSCompareFunc)comp_call_id, [callid UTF8String])) { - [LinphoneLogger log:LinphoneLoggerWarning format:@"Call id [%@] already handled",callid]; + Linphone_warn(@"Call id [%@] already handled",callid); return; }; - if ([pendindCallIdFromRemoteNotif count] > 10 /*max number of pending notif*/) - [pendindCallIdFromRemoteNotif removeObjectAtIndex:0]; + if ([pushCallIDs count] > 10 /*max number of pending notif*/) + [pushCallIDs removeObjectAtIndex:0]; - [pendindCallIdFromRemoteNotif addObject:callid]; + [pushCallIDs addObject:callid]; } -- (BOOL)shouldAutoAcceptCallForCallId:(NSString*) callId { - for (NSString* pendingNotif in pendindCallIdFromRemoteNotif) { +- (BOOL)popPushCallID:(NSString*) callId { + for (NSString* pendingNotif in pushCallIDs) { if ([pendingNotif compare:callId] == NSOrderedSame) { - [pendindCallIdFromRemoteNotif removeObject:pendingNotif]; + [pushCallIDs removeObject:pendingNotif]; return TRUE; } } diff --git a/Classes/PhoneMainView.m b/Classes/PhoneMainView.m index 7abadbd5e..2d220f2ad 100644 --- a/Classes/PhoneMainView.m +++ b/Classes/PhoneMainView.m @@ -270,10 +270,11 @@ static RootViewManager* rootViewManagerInstance = nil; #pragma mark - Event Functions - (void)textReceived:(NSNotification*)notif { - LinphoneAddress*from = [[notif.userInfo objectForKey:@"from_address"] pointerValue]; + LinphoneAddress* from = [[notif.userInfo objectForKey:@"from_address"] pointerValue]; + NSString* callID = [notif.userInfo objectForKey:@"call-id"]; if(from != nil) { - [self playMessageSound]; - } + [self playMessageSoundForCallID:callID]; + } [self updateApplicationBadgeNumber]; } @@ -653,22 +654,31 @@ static RootViewManager* rootViewManagerInstance = nil; #pragma mark - ActionSheet Functions -- (void)playMessageSound { +- (void)playMessageSoundForCallID:(NSString*)callID { if ([UIApplication sharedApplication].applicationState != UIApplicationStateBackground) { - if(![self removeInhibitedEvent:kLinphoneTextReceived]) { - [[LinphoneManager instance] playMessageSound]; + LinphoneManager* lm = [LinphoneManager instance]; + // if the message was already received through a push notif, we don't need to ring + if( ![lm popPushCallID:callID] ) { + [lm playMessageSound]; } } } - (void)displayIncomingCall:(LinphoneCall*) call{ - LinphoneCallLog* callLog=linphone_call_get_call_log(call); - NSString* callId=[NSString stringWithUTF8String:linphone_call_log_get_call_id(callLog)]; + LinphoneCallLog* callLog = linphone_call_get_call_log(call); + NSString* callId = [NSString stringWithUTF8String:linphone_call_log_get_call_id(callLog)]; if ([UIApplication sharedApplication].applicationState != UIApplicationStateBackground) { - if ([[LinphoneManager instance] shouldAutoAcceptCallForCallId:callId]){ - [[LinphoneManager instance] acceptCall:call]; - }else { + LinphoneManager* lm = [LinphoneManager instance]; + BOOL callIDFromPush = [lm popPushCallID:callId]; + BOOL autoAnswer = [lm lpConfigBoolForKey:@"autoanswer_notif_preference"]; + + if (callIDFromPush && autoAnswer){ + // accept call automatically + [lm acceptCall:call]; + + } else { + IncomingCallViewController *controller = nil; if( ![currentView.name isEqualToString:[IncomingCallViewController compositeViewDescription].name]){ controller = DYNAMIC_CAST([self changeCurrentView:[IncomingCallViewController compositeViewDescription] push:TRUE],IncomingCallViewController); @@ -676,11 +686,12 @@ static RootViewManager* rootViewManagerInstance = nil; // controller is already presented, don't bother animating a transition controller = DYNAMIC_CAST([self.mainViewController getCurrentViewController],IncomingCallViewController); } - AudioServicesPlaySystemSound([LinphoneManager instance].sounds.vibrate); + AudioServicesPlaySystemSound(lm.sounds.vibrate); if(controller != nil) { [controller setCall:call]; [controller setDelegate:self]; } + } } } From d9141116050924f2ad43787fde5679460c565a01 Mon Sep 17 00:00:00 2001 From: Guillaume BIENKOWSKI Date: Fri, 16 Jan 2015 14:01:28 +0100 Subject: [PATCH 10/25] Update linphone for bad regression on calls --- submodules/linphone | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/submodules/linphone b/submodules/linphone index f2a4cb60d..47c92f50f 160000 --- a/submodules/linphone +++ b/submodules/linphone @@ -1 +1 @@ -Subproject commit f2a4cb60d2928f96b5300011aa8398d14c8e22a2 +Subproject commit 47c92f50fa441b3f958e133c45abb9d2cd57e0d8 From b1ebb7ef4c2da951a737b1693c4d2ef80ee9eaf9 Mon Sep 17 00:00:00 2001 From: Guillaume BIENKOWSKI Date: Fri, 16 Jan 2015 14:38:22 +0100 Subject: [PATCH 11/25] Fix #1993: search bar misplaced on ipad landscape --- Classes/ContactsViewController.m | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/Classes/ContactsViewController.m b/Classes/ContactsViewController.m index 417838d6e..60f8541de 100644 --- a/Classes/ContactsViewController.m +++ b/Classes/ContactsViewController.m @@ -148,6 +148,16 @@ static UICompositeViewDescription *compositeDescription = nil; [super viewWillDisappear:animated]; } +- (void)relayoutTableView { + CGRect subViewFrame= self.view.frame; + // let the toolBar be visible + subViewFrame.origin.y += self.toolBar.frame.size.height; + subViewFrame.size.height -= self.toolBar.frame.size.height; + [UIView animateWithDuration:0.2 animations:^{ + self.tableView.frame = subViewFrame; + }]; +} + - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; @@ -166,19 +176,17 @@ static UICompositeViewDescription *compositeDescription = nil; [self.view addSubview:picker.view]; self.sysViewController = picker; + self.searchBar.hidden = TRUE; } else if( !use_system && !self.tableController ){ - CGRect subViewFrame= self.view.frame; - // let the toolBar be visible - subViewFrame.origin.y += self.toolBar.frame.size.height; - subViewFrame.size.height -= self.toolBar.frame.size.height; self.tableController = [[[ContactsTableViewController alloc] init] autorelease]; self.tableView = [[[UITableView alloc] init] autorelease]; self.tableController.view = self.tableView; - self.tableView.frame = subViewFrame; + + [self relayoutTableView]; self.tableView.dataSource = self.tableController; self.tableView.delegate = self.tableController; @@ -316,6 +324,15 @@ static UICompositeViewDescription *compositeDescription = nil; [searchBar resignFirstResponder]; } +#pragma mark - Rotation handling + +- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { + [super didRotateFromInterfaceOrientation:fromInterfaceOrientation]; + // the searchbar overlaps the subview in most rotation cases, we have to re-layout the view manually: + [self relayoutTableView]; +} + + #pragma mark - ABPeoplePickerDelegate -(void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker From 08dbcc7d3e58064b90207988c8a852b6cca9e5dd Mon Sep 17 00:00:00 2001 From: Guillaume BIENKOWSKI Date: Fri, 16 Jan 2015 17:31:59 +0100 Subject: [PATCH 12/25] Update linphone --- submodules/linphone | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/submodules/linphone b/submodules/linphone index 47c92f50f..d282ec6ad 160000 --- a/submodules/linphone +++ b/submodules/linphone @@ -1 +1 @@ -Subproject commit 47c92f50fa441b3f958e133c45abb9d2cd57e0d8 +Subproject commit d282ec6ad9c05e1e18c2cb9a917cb6b4f417e56d From 8d69560475cae3c03761e7799429b6cc3f8a34a8 Mon Sep 17 00:00:00 2001 From: Guillaume BIENKOWSKI Date: Fri, 16 Jan 2015 17:58:42 +0100 Subject: [PATCH 13/25] Prevent the wizard from freezing when an invalid username/domain is entered in External account --- Classes/Base.lproj/WizardViews.xib | 4 +- Classes/WizardViewController.h | 2 +- Classes/WizardViewController.m | 49 +++++++++++++++++++------ Resources/en.lproj/Localizable.strings | 4 +- Resources/fr.lproj/Localizable.strings | Bin 27962 -> 28014 bytes Resources/ru.lproj/Localizable.strings | Bin 27436 -> 27460 bytes ar.lproj/Localizable.strings | Bin 26846 -> 26882 bytes 7 files changed, 43 insertions(+), 16 deletions(-) diff --git a/Classes/Base.lproj/WizardViews.xib b/Classes/Base.lproj/WizardViews.xib index c37a761cc..a493a34eb 100644 --- a/Classes/Base.lproj/WizardViews.xib +++ b/Classes/Base.lproj/WizardViews.xib @@ -111,11 +111,11 @@ - +