From 9feeeee73bd587f101fcc6e64de8a544318fdcf4 Mon Sep 17 00:00:00 2001 From: Gautier Pelloux-Prayer Date: Tue, 31 May 2016 14:25:22 +0200 Subject: [PATCH] Contact: update linphone to fix crash when accessing apple sqlite databases (contact, photo) --- CHANGELOG.md | 1 + Classes/Contact.h | 4 ++ Classes/Contact.m | 86 +++++++++++++++++++++++++++++++++ Classes/ContactDetailsView.m | 6 +-- Classes/ContactsListTableView.m | 4 +- Classes/Utils/FastAddressBook.h | 4 -- Classes/Utils/FastAddressBook.m | 72 --------------------------- submodules/cmake-builder | 2 +- submodules/linphone | 2 +- 9 files changed, 98 insertions(+), 83 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cc10cf7d9..10040bec3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ Group changes to describe their impact on the project, as follows: ### Fixed - Fix invalid photo rotation when using Camera for avatars +- Fix self avatar save when using camera - Parse user input as SIP address or phone number depending on default account settings: if "substitute + by country code" is set, consider inputs to be phone numbers, otherwise SIP addresses. - Automatically start call when answering from within notification in iOS9+ diff --git a/Classes/Contact.h b/Classes/Contact.h index 106ac526d..5248313d0 100644 --- a/Classes/Contact.h +++ b/Classes/Contact.h @@ -28,6 +28,7 @@ - (instancetype)initWithPerson:(ABRecordRef)person; - (instancetype)initWithFriend:(LinphoneFriend *) friend; +- (void)setAvatar:(UIImage *)avatar; - (BOOL)setSipAddress:(NSString *)sip atIndex:(NSInteger)index; - (BOOL)setEmail:(NSString *)email atIndex:(NSInteger)index; - (BOOL)setPhoneNumber:(NSString *)phone atIndex:(NSInteger)index; @@ -39,4 +40,7 @@ - (BOOL)removeSipAddressAtIndex:(NSInteger)index; - (BOOL)removePhoneNumberAtIndex:(NSInteger)index; - (BOOL)removeEmailAtIndex:(NSInteger)index; + +- (int)remove; +- (BOOL)save; @end diff --git a/Classes/Contact.m b/Classes/Contact.m index 453c914fb..2e6866fd9 100644 --- a/Classes/Contact.m +++ b/Classes/Contact.m @@ -47,6 +47,73 @@ _person = nil; _friend = NULL; } +#pragma mark - Misc +- (int)remove { + // Remove contact from book + if (_person && ABRecordGetRecordID(_person) != kABRecordInvalidID) { + CFErrorRef error = NULL; + ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error); + if (!addressBook) { + LOGE(@"Cannot retrieve address book"); + return -3; + } + ABAddressBookGetAuthorizationStatus(); + + ABAddressBookRemoveRecord(addressBook, _person, &error); + if (error != NULL) { + LOGE(@"Remove contact %p: Fail(%@)", self, [(__bridge NSError *)error localizedDescription]); + CFRelease(addressBook); + return -3; + } else { + LOGI(@"Remove contact %p: Success!", self); + } + + // Save address book + error = NULL; + ABAddressBookSave(addressBook, &error); + + _person = nil; + + if (error != NULL) { + LOGE(@"Save AddressBook: Fail(%@)", [(__bridge NSError *)error localizedDescription]); + } else { + LOGI(@"Save AddressBook: Success!"); + } + CFRelease(addressBook); + return error ? -1 : 0; + } + return -2; +} + +- (BOOL)save { + CFErrorRef error = NULL; + ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error); + if (!addressBook) { + LOGE(@"Cannot retrieve address book"); + return FALSE; + } + if (ABRecordGetRecordID(_person) == kABRecordInvalidID) { + if (ABAddressBookAddRecord(addressBook, _person, &error)) { + LOGI(@"Add contact %p: Success!", _person); + } else { + LOGE(@"Add contact %p: Fail(%@)", _person, [(__bridge NSError *)error localizedDescription]); + CFRelease(addressBook); + return FALSE; + } + } + + // Save address book + error = NULL; + if (ABAddressBookSave(addressBook, &error)) { + LOGI(@"Save AddressBook: Success!"); + } else { + LOGE(@"Save AddressBook: Fail(%@)", + error ? [(__bridge NSError *)error localizedDescription] : @"unknown error"); + return FALSE; + } + CFRelease(addressBook); + return error == NULL; +} #pragma mark - Getters - (UIImage *)avatar:(BOOL)thumbnail { @@ -124,6 +191,25 @@ } } +- (void)setAvatar:(UIImage *)avatar { + if (_person) { + CFErrorRef error = NULL; + if (!ABPersonRemoveImageData(_person, &error)) { + LOGW(@"Can't remove entry: %@", [(__bridge NSError *)error localizedDescription]); + } + NSData *dataRef = UIImageJPEGRepresentation(avatar, 0.9f); + CFDataRef cfdata = CFDataCreate(NULL, [dataRef bytes], [dataRef length]); + + if (!ABPersonSetImageData(_person, cfdata, &error)) { + LOGW(@"Can't add entry: %@", [(__bridge NSError *)error localizedDescription]); + } + + CFRelease(cfdata); + } else { + LOGW(@"%s: Cannot do it when using LinphoneFriend, skipping", __FUNCTION__); + } +} + - (BOOL)setSipAddress:(NSString *)sip atIndex:(NSInteger)index { BOOL ret = FALSE; if (_person) { diff --git a/Classes/ContactDetailsView.m b/Classes/ContactDetailsView.m index 702864819..15438ad49 100644 --- a/Classes/ContactDetailsView.m +++ b/Classes/ContactDetailsView.m @@ -61,7 +61,7 @@ - (void)removeContact { inhibUpdate = TRUE; - [[LinphoneManager.instance fastAddressBook] removeContact:_contact]; + [_contact remove]; inhibUpdate = FALSE; [PhoneMainView.instance popCurrentView]; } @@ -73,7 +73,7 @@ } // Add contact to book - [LinphoneManager.instance.fastAddressBook saveContact:_contact]; + [_contact save]; } - (void)selectContact:(Contact *)acontact andReload:(BOOL)reload { @@ -312,7 +312,7 @@ static UICompositeViewDescription *compositeDescription = nil; [VIEW(ImagePickerView).popoverController dismissPopoverAnimated:TRUE]; } - [FastAddressBook setAvatar:image forContact:_contact]; + [_contact setAvatar:image]; [_avatarImage setImage:[FastAddressBook imageForContact:_contact thumbnail:NO] bordered:NO withRoundedRadius:YES]; } diff --git a/Classes/ContactsListTableView.m b/Classes/ContactsListTableView.m index 34c8a414f..6061740d1 100644 --- a/Classes/ContactsListTableView.m +++ b/Classes/ContactsListTableView.m @@ -252,7 +252,7 @@ static int ms_strcmpfuz(const char *fuzzy_word, const char *sentence) { [tableView deleteSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationFade]; } - [[LinphoneManager.instance fastAddressBook] removeContact:contact]; + [contact remove]; [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; [tableView endUpdates]; @@ -276,7 +276,7 @@ static int ms_strcmpfuz(const char *fuzzy_word, const char *sentence) { if ([self.tableView numberOfRowsInSection:indexPath.section] == 1) { [addressBookMap removeObjectForKey:firstChar]; } - [[LinphoneManager.instance fastAddressBook] removeContact:contact]; + [contact remove]; [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(onAddressBookUpdate:) diff --git a/Classes/Utils/FastAddressBook.h b/Classes/Utils/FastAddressBook.h index 059a3f8e3..2dd3e624b 100644 --- a/Classes/Utils/FastAddressBook.h +++ b/Classes/Utils/FastAddressBook.h @@ -28,9 +28,6 @@ @property(readonly, nonatomic) NSMutableDictionary *addressBookMap; - (void)reload; -- (void)saveAddressBook; -- (int)removeContact:(Contact *)contact; -- (BOOL)saveContact:(Contact *)contact; + (BOOL)isAuthorized; @@ -50,6 +47,5 @@ + (NSString *)normalizeSipURI:(NSString *)address; // should be removed + (NSString *)localizedLabel:(NSString *)label; -+ (void)setAvatar:(UIImage *)avatar forContact:(Contact *)contact; @end diff --git a/Classes/Utils/FastAddressBook.m b/Classes/Utils/FastAddressBook.m index b5b9f7660..1adf7fb55 100644 --- a/Classes/Utils/FastAddressBook.m +++ b/Classes/Utils/FastAddressBook.m @@ -246,76 +246,4 @@ void sync_address_book(ABAddressBookRef addressBook, CFDictionaryRef info, void return ret; } -- (int)removeContact:(Contact *)contact { - // Remove contact from book - if (contact.person && ABRecordGetRecordID(contact.person) != kABRecordInvalidID) { - CFErrorRef error = NULL; - ABAddressBookRemoveRecord(addressBook, contact.person, (CFErrorRef *)&error); - if (error != NULL) { - LOGE(@"Remove contact %p: Fail(%@)", contact, [(__bridge NSError *)error localizedDescription]); - } else { - LOGI(@"Remove contact %p: Success!", contact); - } - contact = NULL; - // Save address book - error = NULL; - ABAddressBookSave(addressBook, (CFErrorRef *)&error); - - // TODO: stop reloading the whole address book but just clear the removed entries! - [self loadData]; - - if (error != NULL) { - LOGE(@"Save AddressBook: Fail(%@)", [(__bridge NSError *)error localizedDescription]); - } else { - LOGI(@"Save AddressBook: Success!"); - } - return error ? -1 : 0; - } - return -2; -} - -- (BOOL)saveContact:(Contact *)contact { - CFErrorRef error = NULL; - if (ABRecordGetRecordID(contact.person) == kABRecordInvalidID) { - if (ABAddressBookAddRecord(addressBook, contact.person, (CFErrorRef *)&error)) { - LOGI(@"Add contact %p: Success!", contact.person); - } else { - LOGE(@"Add contact %p: Fail(%@)", contact.person, [(__bridge NSError *)error localizedDescription]); - return FALSE; - } - } - - // Save address book - error = NULL; - if (ABAddressBookSave(addressBook, &error)) { - LOGI(@"Save AddressBook: Success!"); - } else { - LOGE(@"Save AddressBook: Fail(%@)", [(__bridge NSError *)error localizedDescription]); - return FALSE; - } - [self reload]; - - return error == NULL; -} - -+ (void)setAvatar:(UIImage *)avatar forContact:(Contact *)contact { - FastAddressBook *fab = LinphoneManager.instance.fastAddressBook; - CFErrorRef error = NULL; - if (!ABPersonRemoveImageData(contact.person, (CFErrorRef *)&error)) { - LOGI(@"Can't remove entry: %@", [(__bridge NSError *)error localizedDescription]); - } - NSData *dataRef = UIImageJPEGRepresentation(avatar, 0.9f); - CFDataRef cfdata = CFDataCreate(NULL, [dataRef bytes], [dataRef length]); - - [fab saveAddressBook]; - - if (!ABPersonSetImageData(contact.person, cfdata, (CFErrorRef *)&error)) { - LOGI(@"Can't add entry: %@", [(__bridge NSError *)error localizedDescription]); - } else { - [fab saveAddressBook]; - } - - CFRelease(cfdata); -} - @end diff --git a/submodules/cmake-builder b/submodules/cmake-builder index 4a4f51f45..b08d4cedd 160000 --- a/submodules/cmake-builder +++ b/submodules/cmake-builder @@ -1 +1 @@ -Subproject commit 4a4f51f455f5d1b344b17b97388fb359ac8517ed +Subproject commit b08d4cedd0153aa3dbe8a672bf6e8be5f09b2f19 diff --git a/submodules/linphone b/submodules/linphone index e4c674c2e..6574a95fd 160000 --- a/submodules/linphone +++ b/submodules/linphone @@ -1 +1 @@ -Subproject commit e4c674c2e3887063aa2c73163c748acccd5fd12b +Subproject commit 6574a95fd755216b8b91616772cdf4f986214cc6