From 2a7b6c4a7fefa3a0db45fea8ce499e4c1b048296 Mon Sep 17 00:00:00 2001 From: Danmei Chen Date: Mon, 12 Jul 2021 14:33:46 +0200 Subject: [PATCH] Revert "migration all images from cacheDirectory to imagesDirectory, to avoid automaic clear of cache" This reverts commit 88e807c5290439146612da016b708a658e73c0cc. --- Classes/ChatConversationView.h | 7 +-- Classes/ChatConversationView.m | 52 ++++++++++++++++++--- Classes/LinphoneManager.h | 2 - Classes/LinphoneManager.m | 53 ++++++---------------- Classes/LinphoneUI/UIChatBubblePhotoCell.m | 14 +++--- Classes/LinphoneUI/UIChatBubbleTextCell.m | 18 ++++---- Classes/LinphoneUI/UIChatContentView.m | 4 +- Classes/Utils/FileTransferDelegate.m | 12 ++--- 8 files changed, 87 insertions(+), 75 deletions(-) diff --git a/Classes/ChatConversationView.h b/Classes/ChatConversationView.h index 06bb89c17..32595c83c 100644 --- a/Classes/ChatConversationView.h +++ b/Classes/ChatConversationView.h @@ -95,9 +95,9 @@ + (void)markAsRead:(LinphoneChatRoom *)chatRoom; + (void)autoDownload:(LinphoneChatMessage *)message; +(NSString *)getKeyFromFileType:(NSString *)fileType fileName:(NSString *)name; -+ (NSURL *)getFileUrl:(NSString *)name; -+ (void)writeFileInImagesDirectory:(NSData *)data name:(NSString *)name; -+ (NSData *)getFileData:(NSString *)name; ++ (NSURL *)getCacheFileUrl:(NSString *)name; ++ (void)writeFileInCache:(NSData *)data name:(NSString *)name; ++ (NSData *)getCacheFileData:(NSString *)name; + (void)writeMediaToGallery:(NSString *)name fileType:(NSString *)fileType; +(UIImage *)getBasicImage; +(UIImage*)drawText:(NSString*)text image:(UIImage *)image textSize:(CGFloat)textSize; @@ -121,6 +121,7 @@ - (void)showFileDownloadError; - (NSURL *)getICloudFileUrl:(NSString *)name; +- (BOOL)writeFileInICloud:(NSData *)data fileURL:(NSURL *)fileURL; - (void)removeCallBacks; @end diff --git a/Classes/ChatConversationView.m b/Classes/ChatConversationView.m index bfdca00f3..a365d68e6 100644 --- a/Classes/ChatConversationView.m +++ b/Classes/ChatConversationView.m @@ -901,7 +901,7 @@ static UICompositeViewDescription *compositeDescription = nil; } + (void)writeMediaToGallery:(NSString *)name fileType:(NSString *)fileType { - NSString *filePath = [LinphoneManager validFilePath:name]; + NSString *filePath = [[LinphoneManager cacheDirectory] stringByAppendingPathComponent:name]; NSFileManager *fileManager = [NSFileManager defaultManager]; if ([fileManager fileExistsAtPath:filePath]) { NSData* data = [NSData dataWithContentsOfFile:filePath]; @@ -1324,18 +1324,18 @@ void on_chat_room_conference_alert(LinphoneChatRoom *cr, const LinphoneEventLog [PhoneMainView.instance fullScreen:NO]; } -+ (NSData *)getFileData: (NSString *)name { - NSString *filePath = [LinphoneManager validFilePath:name]; ++ (NSData *)getCacheFileData: (NSString *)name { + NSString *filePath = [[LinphoneManager cacheDirectory] stringByAppendingPathComponent:name]; return [NSData dataWithContentsOfFile:filePath]; } -+ (NSURL *)getFileUrl: (NSString *)name { - NSString *filePath = [LinphoneManager validFilePath:name]; ++ (NSURL *)getCacheFileUrl: (NSString *)name { + NSString *filePath = [[LinphoneManager cacheDirectory] stringByAppendingPathComponent:name]; return [NSURL fileURLWithPath:filePath]; } -+ (void)writeFileInImagesDirectory:(NSData *)data name:(NSString *)name { - NSString *filePath = [[LinphoneManager imagesDirectory] stringByAppendingPathComponent:name]; ++ (void)writeFileInCache:(NSData *)data name:(NSString *)name { + NSString *filePath = [[LinphoneManager cacheDirectory] stringByAppendingPathComponent:name]; if (name || [name isEqualToString:@""]) { LOGW(@"try to write file in %@", filePath); } @@ -1364,6 +1364,44 @@ void on_chat_room_conference_alert(LinphoneChatRoom *cr, const LinphoneEventLog return nil; } +- (BOOL)writeFileInICloud:(NSData *)data fileURL:(NSURL *)fileURL { + NSFileManager *fileManager = [NSFileManager defaultManager]; + BOOL useMyDevice = FALSE; + if (@available(iOS 11.0, *)) { + useMyDevice = TRUE; + } + + if (!useMyDevice && ![[fileManager URLForUbiquityContainerIdentifier:nil]URLByAppendingPathComponent:@"Documents"]) { + //notify : set configuration to use icloud + [[[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Info", nil) message:NSLocalizedString(@"ICloud Drive is unavailable.", nil) delegate:nil cancelButtonTitle:NSLocalizedString(@"Cancel", nil) otherButtonTitles:nil, nil] show]; + return FALSE; + } + + NSString *fileName = fileURL.lastPathComponent; + if ([fileManager fileExistsAtPath:[fileURL path]] || [fileName hasPrefix:@"recording"]) { + // if it exists, replace the file. If it's a record file, copy the file + return [data writeToURL:fileURL atomically:TRUE]; + } else { + // get the url of localfile + NSString *filePath = [[LinphoneManager cacheDirectory] stringByAppendingPathComponent:fileName]; + NSURL *localURL = nil; + if (fileName || [fileName isEqualToString:@""]) { + LOGW(@"[writeFileInICloud] try to write file in %@", filePath); + } + if ([fileManager createFileAtPath:filePath contents:data attributes:nil]) { + localURL = [NSURL fileURLWithPath:filePath]; + } + + NSError *error; + if ([[NSFileManager defaultManager] setUbiquitous:YES itemAtURL:localURL destinationURL:fileURL error:&error]) { + return TRUE; + } else { + LOGE(@"Cannot write file in Icloud file [%@]",[error localizedDescription]); + return FALSE; + } + } +} + - (void)deleteFileWithUuid:(NSUUID *)uuid { [_fileContext deleteContentWithUuid:uuid]; [self refreshImageDrawer]; diff --git a/Classes/LinphoneManager.h b/Classes/LinphoneManager.h index 1054595b7..12ff03ce1 100644 --- a/Classes/LinphoneManager.h +++ b/Classes/LinphoneManager.h @@ -135,8 +135,6 @@ typedef struct _LinphoneManagerSounds { + (NSString *)documentFile:(NSString *)file; + (NSString*)dataFile:(NSString*)file; + (NSString*)cacheDirectory; -+ (NSString *)imagesDirectory; -+ (NSString *)validFilePath:(NSString *)name; // migration + (NSString *)oldPreferenceFile:(NSString *)file; + (NSString *)oldDataFile:(NSString *)file; diff --git a/Classes/LinphoneManager.m b/Classes/LinphoneManager.m index d2d90f217..9e04c7c4b 100644 --- a/Classes/LinphoneManager.m +++ b/Classes/LinphoneManager.m @@ -253,9 +253,6 @@ struct codec_name_pref_table codec_pref_table[] = {{"speex", 8000, "speex_8k_pre [self renameDefaultSettings]; [self copyDefaultSettings]; [self overrideDefaultSettings]; - if (![self lpConfigBoolForKey:@"migration_images_done" withDefault:FALSE]) { - [self migrationAllImages]; - } [self lpConfigSetString:[LinphoneManager dataFile:@"linphone.db"] forKey:@"uri" inSection:@"storage"]; [self lpConfigSetString:[LinphoneManager dataFile:@"x3dh.c25519.sqlite3"] forKey:@"x3dh_db_path" inSection:@"lime"]; @@ -1406,7 +1403,7 @@ void popup_link_account_cb(LinphoneAccountCreator *creator, LinphoneAccountCreat /* Use the rootca from framework, which is already set*/ //linphone_core_set_root_ca(theLinphoneCore, [LinphoneManager bundleFile:@"rootca.pem"].UTF8String); - linphone_core_set_user_certificates_path(theLinphoneCore, linphone_factory_get_data_dir(linphone_factory_get(), kLinphoneMsgNotificationAppGroupId.UTF8String)); + linphone_core_set_user_certificates_path(theLinphoneCore, [LinphoneManager cacheDirectory].UTF8String); /* The core will call the linphone_iphone_configuring_status_changed callback when the remote provisioning is loaded (or skipped). @@ -1667,17 +1664,6 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) { linphone_core_refresh_registers(theLinphoneCore); // just to make sure REGISTRATION is up to date } -- (void)migrationAllImages { - NSFileManager *fileManager = [NSFileManager defaultManager]; - NSArray *images = [fileManager contentsOfDirectoryAtPath:[LinphoneManager cacheDirectory] error:NULL]; - - for (NSString *image in images) - { - [fileManager copyItemAtPath:[[LinphoneManager cacheDirectory] stringByAppendingPathComponent:image] toPath:[[LinphoneManager imagesDirectory] stringByAppendingPathComponent:image] error:nil]; - } - [self lpConfigSetBool:TRUE forKey:@"migration_images_done"]; -} - - (void)migrateImportantFiles { if ([LinphoneManager copyFile:[LinphoneManager oldPreferenceFile:@"linphonerc"] destination:[LinphoneManager preferenceFile:@"linphonerc"] override:TRUE ignore:TRUE]) { [NSFileManager.defaultManager @@ -1893,22 +1879,6 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) { return [fullPath stringByAppendingPathComponent:file]; } -+ (NSString *)imagesDirectory { - NSURL *basePath = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:kLinphoneMsgNotificationAppGroupId]; - NSString *fullPath = [[basePath path] stringByAppendingString:@"/Library/Images/"]; - if (![[NSFileManager defaultManager] fileExistsAtPath:fullPath]) { - NSError *error; - LOGW(@"Download path %@ does not exist, creating it.", fullPath); - if (![[NSFileManager defaultManager] createDirectoryAtPath:fullPath - withIntermediateDirectories:YES - attributes:nil - error:&error]) { - LOGE(@"Create download path directory error: %@", error.description); - } - } - return fullPath; -} - + (NSString *)cacheDirectory { NSURL *basePath = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:kLinphoneMsgNotificationAppGroupId]; NSString *fullPath = [[basePath path] stringByAppendingString:@"/Library/Caches/"]; @@ -1923,15 +1893,20 @@ static int comp_call_state_paused(const LinphoneCall *call, const void *param) { } } return fullPath; -} - -+ (NSString *)validFilePath:(NSString *)name { - NSString *filePath = [[LinphoneManager imagesDirectory] stringByAppendingPathComponent:name]; - if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) { - return filePath; + + /*LinphoneFactory *factory = linphone_factory_get(); + NSString *cachePath = [NSString stringWithUTF8String:linphone_factory_get_download_dir(factory, kLinphoneMsgNotificationAppGroupId.UTF8String)]; + BOOL isDir = NO; + NSError *error; + // cache directory must be created if not existing + if (![[NSFileManager defaultManager] fileExistsAtPath:cachePath isDirectory:&isDir] && isDir == NO) { + [[NSFileManager defaultManager] createDirectoryAtPath:cachePath + withIntermediateDirectories:NO + attributes:nil + error:&error]; + LOGW(@"create new cache directory"); } - // if migration (move files of cacheDirectory to imagesDirectory) failed - return [[LinphoneManager cacheDirectory] stringByAppendingPathComponent:name]; + return cachePath;*/ } + (NSString *)oldPreferenceFile:(NSString *)file { diff --git a/Classes/LinphoneUI/UIChatBubblePhotoCell.m b/Classes/LinphoneUI/UIChatBubblePhotoCell.m index d96ae3cb2..d2f99565f 100644 --- a/Classes/LinphoneUI/UIChatBubblePhotoCell.m +++ b/Classes/LinphoneUI/UIChatBubblePhotoCell.m @@ -266,7 +266,7 @@ ms_free(cPath); [LinphoneManager setValueInMessageAppData:filePath forKey:@"encryptedfile" inMessage:self.message]; } else { - filePath = [LinphoneManager validFilePath:fileName]; + filePath = [[LinphoneManager cacheDirectory] stringByAppendingPathComponent:fileName]; } } if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) { @@ -435,7 +435,7 @@ if (!filePath) { NSString *localVideo = [LinphoneManager getMessageAppDataForKey:@"localvideo" inMessage:self.message]; NSString *localFile = [LinphoneManager getMessageAppDataForKey:@"localfile" inMessage:self.message]; - filePath = [LinphoneManager validFilePath:(localVideo?:localFile)]; + filePath = [[LinphoneManager cacheDirectory] stringByAppendingPathComponent:(localVideo?:localFile)]; } if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) { @@ -492,8 +492,8 @@ return; } NSString *name = [LinphoneManager getMessageAppDataForKey:@"localfile" inMessage:self.message]; - if([[NSFileManager defaultManager] fileExistsAtPath: [LinphoneManager validFilePath:name]]) { - [view openFileWithURL:[ChatConversationView getFileUrl:name]]; + if([[NSFileManager defaultManager] fileExistsAtPath:[[LinphoneManager cacheDirectory] stringByAppendingPathComponent:name]]) { + [view openFileWithURL:[ChatConversationView getCacheFileUrl:name]]; } else { [view openFileWithURL:[view getICloudFileUrl:name]]; } @@ -540,16 +540,16 @@ NSString *localImage = [LinphoneManager getMessageAppDataForKey:@"localimage" inMessage:self.message]; NSString *localFile = [LinphoneManager getMessageAppDataForKey:@"localfile" inMessage:self.message]; NSString *imageName = NULL; - if (localImage && [[NSFileManager defaultManager] fileExistsAtPath: [LinphoneManager validFilePath:localImage]]) { + if (localImage && [[NSFileManager defaultManager] fileExistsAtPath:[[LinphoneManager cacheDirectory] stringByAppendingPathComponent:localImage]]) { imageName = localImage; - } else if (localFile && [[NSFileManager defaultManager] fileExistsAtPath:[LinphoneManager validFilePath:localFile]]) { + } else if (localFile && [[NSFileManager defaultManager] fileExistsAtPath:[[LinphoneManager cacheDirectory] stringByAppendingPathComponent:localFile]]) { if ([localFile hasSuffix:@"JPG"] || [localFile hasSuffix:@"PNG"] || [localFile hasSuffix:@"jpg"] || [localFile hasSuffix:@"png"]) { imageName = localFile; } } if (imageName) { - NSData *data = [NSData dataWithContentsOfFile:[LinphoneManager validFilePath:imageName]]; + NSData *data = [NSData dataWithContentsOfFile:[[LinphoneManager cacheDirectory] stringByAppendingPathComponent:imageName]]; UIImage *image = [[UIImage alloc] initWithData:data]; if (image) [view setImage:image]; diff --git a/Classes/LinphoneUI/UIChatBubbleTextCell.m b/Classes/LinphoneUI/UIChatBubbleTextCell.m index e5271015c..2dd4c2688 100644 --- a/Classes/LinphoneUI/UIChatBubbleTextCell.m +++ b/Classes/LinphoneUI/UIChatBubbleTextCell.m @@ -75,7 +75,7 @@ for(NSString *path in [encrptedFilePaths allValues]) { if (![path isEqualToString:@""]) { LOGW(@"[vfs]s remove item at %@",path); - if ([path isEqualToString:[LinphoneManager imagesDirectory]]) { + if ([path isEqualToString:[LinphoneManager cacheDirectory]]) { LOGE(@"[vfs] something is wrong, can not delete the cache directory"); break; } @@ -92,7 +92,7 @@ if (![filePath isEqualToString:@""]) { NSError *error = nil; LOGW(@"[vfs] remove item at %@",filePath); - if ([filePath isEqualToString:[LinphoneManager imagesDirectory]]) { + if ([filePath isEqualToString:[LinphoneManager cacheDirectory]]) { LOGE(@"[vfs] something is wrong, can not delete the cache directory"); } else { [[NSFileManager defaultManager] removeItemAtPath:filePath error:&error]; @@ -327,7 +327,7 @@ NSString *name = [NSString stringWithUTF8String:linphone_content_get_name(content)]; NSString *filePath = [encrptedFilePaths valueForKey:name]; if (filePath == NULL) { - filePath = [LinphoneManager validFilePath:name]; + filePath = [[LinphoneManager cacheDirectory] stringByAppendingPathComponent:name]; } [newfileContext addObject:[NSData dataWithContentsOfFile:filePath] name:name type:[NSString stringWithUTF8String:linphone_content_get_type(content)]]; } @@ -354,11 +354,11 @@ const char *text = linphone_chat_message_get_text_content(_message); NSString *str = text ? [NSString stringWithUTF8String:text] : NULL; if (localImage) { - [_chatRoomDelegate resendFile: (data?:[ChatConversationView getFileData:localImage]) withName:localImage type:@"image" key:@"localimage" message:str]; + [_chatRoomDelegate resendFile: (data?:[ChatConversationView getCacheFileData:localImage]) withName:localImage type:@"image" key:@"localimage" message:str]; } else if (localVideo) { - [_chatRoomDelegate resendFile:(data?:[ChatConversationView getFileData:localVideo]) withName:localVideo type:@"video" key:@"localvideo" message:str]; + [_chatRoomDelegate resendFile:(data?:[ChatConversationView getCacheFileData:localVideo]) withName:localVideo type:@"video" key:@"localvideo" message:str]; } else { - [_chatRoomDelegate resendFile:(data?:[ChatConversationView getFileData:localFile]) withName:localFile type:@"image" key:@"localfile" message:str]; + [_chatRoomDelegate resendFile:(data?:[ChatConversationView getCacheFileData:localFile]) withName:localFile type:@"image" key:@"localfile" message:str]; } }); } else { @@ -441,7 +441,7 @@ static const CGFloat CELL_MESSAGE_Y_MARGIN = 44; NSString *type = [NSString stringWithUTF8String:linphone_content_get_type(content)]; NSString *name = [NSString stringWithUTF8String:linphone_content_get_name(content)]; if (!filePath) { - filePath = [LinphoneManager validFilePath:name]; + filePath = [[LinphoneManager cacheDirectory] stringByAppendingPathComponent:name]; } UIImage *image = nil; @@ -502,7 +502,7 @@ static const CGFloat CELL_MESSAGE_Y_MARGIN = 44; NSString *name = [NSString stringWithUTF8String:linphone_content_get_name(content)]; NSString *filePath=[encrptedFilePaths valueForKey:name]; if (filePath == NULL) { - filePath = [LinphoneManager validFilePath:name]; + filePath = [[LinphoneManager cacheDirectory] stringByAppendingPathComponent:name]; } image = [UIChatBubbleTextCell getImageFromContent:content filePath:filePath]; @@ -562,7 +562,7 @@ static const CGFloat CELL_MESSAGE_Y_MARGIN = 44; CGSize originalImageSize = CGSizeMake(230, 50); if (!filePath) { - filePath = [LinphoneManager validFilePath:fileName]; + filePath = [[LinphoneManager cacheDirectory] stringByAppendingPathComponent:fileName]; } if (localFile) { UIImage *image = nil; diff --git a/Classes/LinphoneUI/UIChatContentView.m b/Classes/LinphoneUI/UIChatContentView.m index 45882677f..fd24709cf 100644 --- a/Classes/LinphoneUI/UIChatContentView.m +++ b/Classes/LinphoneUI/UIChatContentView.m @@ -48,7 +48,7 @@ } else { if (_filePath == NULL) { NSString *name = [NSString stringWithUTF8String:linphone_content_get_name(content)]; - _filePath = [LinphoneManager validFilePath:name]; + _filePath = [[LinphoneManager cacheDirectory] stringByAppendingPathComponent:name]; } UIImage *image = [UIChatBubbleTextCell getImageFromContent:content filePath:_filePath]; [self setImage:image]; @@ -67,7 +67,7 @@ -(IBAction)onDownloadClick:(id)sender { _downloadButton.enabled = NO; - linphone_content_set_file_path(_content, [[LinphoneManager imagesDirectory] stringByAppendingPathComponent:[NSString stringWithUTF8String:linphone_content_get_name(_content)]].UTF8String); + linphone_content_set_file_path(_content, [[LinphoneManager cacheDirectory] stringByAppendingPathComponent:[NSString stringWithUTF8String:linphone_content_get_name(_content)]].UTF8String); linphone_chat_message_download_content(_message, _content); } diff --git a/Classes/Utils/FileTransferDelegate.m b/Classes/Utils/FileTransferDelegate.m index d8d20670b..970288c86 100644 --- a/Classes/Utils/FileTransferDelegate.m +++ b/Classes/Utils/FileTransferDelegate.m @@ -108,13 +108,13 @@ static void file_transfer_progress_indication_send(LinphoneChatMessage *message, return; } [LinphoneManager.instance.fileTransferDelegates addObject:self]; - [ChatConversationView writeFileInImagesDirectory:data name:name]; + [ChatConversationView writeFileInCache:data name:name]; LinphoneContent *content = linphone_core_create_content(linphone_chat_room_get_core(chatRoom)); linphone_content_set_type(content, [type UTF8String]); linphone_content_set_subtype(content, [subtype UTF8String]); linphone_content_set_name(content, [name UTF8String]); - linphone_content_set_file_path(content, [[LinphoneManager imagesDirectory] stringByAppendingPathComponent:name].UTF8String); + linphone_content_set_file_path(content, [[LinphoneManager cacheDirectory] stringByAppendingPathComponent:name].UTF8String); _message = linphone_chat_room_create_file_transfer_message(chatRoom, content); BOOL isOneToOneChat = linphone_chat_room_get_capabilities(chatRoom) & LinphoneChatRoomCapabilitiesOneToOne; if (!isOneToOneChat && (_text!=nil && ![_text isEqualToString:@""])) @@ -143,13 +143,13 @@ static void file_transfer_progress_indication_send(LinphoneChatMessage *message, NSString *name = [context.namesArray objectAtIndex:i]; NSData *data = [context.datasArray objectAtIndex:i]; - [ChatConversationView writeFileInImagesDirectory:data name:name]; + [ChatConversationView writeFileInCache:data name:name]; linphone_content_set_type(content, [type UTF8String]); linphone_content_set_subtype(content, [name.pathExtension UTF8String]); linphone_content_set_name(content, [name UTF8String]); - linphone_content_set_file_path(content, [[LinphoneManager imagesDirectory] stringByAppendingPathComponent:name].UTF8String); + linphone_content_set_file_path(content, [[LinphoneManager cacheDirectory] stringByAppendingPathComponent:name].UTF8String); [names addObject:name]; [types addObject:type]; linphone_chat_message_add_file_content(_message, content); @@ -179,7 +179,7 @@ static void file_transfer_progress_indication_send(LinphoneChatMessage *message, } - (void)uploadFile:(NSData *)data forChatRoom:(LinphoneChatRoom *)chatRoom withName:(NSString *)name { - NSURL *url = [ChatConversationView getFileUrl:name]; + NSURL *url = [ChatConversationView getCacheFileUrl:name]; AVAsset *asset = [AVURLAsset URLAssetWithURL:url options:nil]; NSString *fileType = [[asset tracksWithMediaType:AVMediaTypeVideo] count] > 0 ? @"video" : @"file"; NSString *key = [ChatConversationView getKeyFromFileType:fileType fileName:name]; @@ -202,7 +202,7 @@ static void file_transfer_progress_indication_send(LinphoneChatMessage *message, LOGI(@"%p Downloading content in %p ", self, message); linphone_chat_message_cbs_set_file_transfer_progress_indication(linphone_chat_message_get_callbacks(_message), file_transfer_progress_indication_recv); - linphone_content_set_file_path(content, [[LinphoneManager imagesDirectory] stringByAppendingPathComponent:[NSString stringWithUTF8String:linphone_content_get_name(content)]].UTF8String); + linphone_content_set_file_path(content, [[LinphoneManager cacheDirectory] stringByAppendingPathComponent:[NSString stringWithUTF8String:linphone_content_get_name(content)]].UTF8String); linphone_chat_message_download_content(_message, content); return TRUE;