From 7889b0610b4a874c3c9d4613a881821a1ca93701 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Tue, 13 Dec 2016 16:09:12 +0100 Subject: [PATCH] Store weak references of chat messages in the chat room to be able to returned the same LinphoneChatMessage object to the application. --- coreapi/chat.c | 14 ++++++++++++++ coreapi/message_storage.c | 25 ++++++++++++++++++++++--- coreapi/private.h | 2 ++ tester/message_tester.c | 21 ++++++++++++--------- 4 files changed, 50 insertions(+), 12 deletions(-) diff --git a/coreapi/chat.c b/coreapi/chat.c index 0e95b0500..da87a6e0c 100644 --- a/coreapi/chat.c +++ b/coreapi/chat.c @@ -134,6 +134,7 @@ static void _linphone_chat_room_destroy(LinphoneChatRoom *cr) { if (cr->pending_message) linphone_chat_message_destroy(cr->pending_message); ms_free(cr->peer); + if (cr->weak_messages != NULL) bctbx_list_free(cr->weak_messages); } void linphone_chat_message_set_state(LinphoneChatMessage *msg, LinphoneChatMessageState state) { @@ -307,6 +308,18 @@ void linphone_chat_room_release(LinphoneChatRoom *cr) { linphone_chat_room_unref(cr); } +static void on_weak_message_destroy(void *obj, belle_sip_object_t *message_being_destroyed) { + LinphoneChatRoom *cr = (LinphoneChatRoom *)obj; + cr->weak_messages = bctbx_list_remove(cr->weak_messages, message_being_destroyed); +} + +void linphone_chat_room_add_weak_message(LinphoneChatRoom *cr, LinphoneChatMessage *cm) { + bctbx_list_t *item = bctbx_list_find(cr->weak_messages, cm); + if (item == NULL) { + cr->weak_messages = bctbx_list_append(cr->weak_messages, belle_sip_object_weak_ref(cm, on_weak_message_destroy, cr)); + } +} + LinphoneChatRoom *linphone_chat_room_ref(LinphoneChatRoom *cr) { belle_sip_object_ref(cr); return cr; @@ -470,6 +483,7 @@ void linphone_chat_message_update_state(LinphoneChatMessage *msg, LinphoneChatMe if (msg->state == LinphoneChatMessageStateDelivered || msg->state == LinphoneChatMessageStateNotDelivered) { // msg is not transient anymore, we can remove it from our transient list and unref it msg->chat_room->transient_messages = bctbx_list_remove(msg->chat_room->transient_messages, msg); + linphone_chat_room_add_weak_message(msg->chat_room, msg); linphone_chat_message_unref(msg); } } diff --git a/coreapi/message_storage.c b/coreapi/message_storage.c index 398c2f451..5e349b600 100644 --- a/coreapi/message_storage.c +++ b/coreapi/message_storage.c @@ -117,6 +117,17 @@ int _linphone_sqlite3_open(const char *db_file, sqlite3 **db) { #ifdef SQLITE_STORAGE_ENABLED +static LinphoneChatMessage * get_weak_message(LinphoneChatRoom *cr, unsigned int storage_id) { + LinphoneChatMessage *cm; + bctbx_list_t *item; + for (item = cr->weak_messages; item != NULL; item = bctbx_list_next(item)) { + cm = (LinphoneChatMessage *)bctbx_list_get_data(item); + if (linphone_chat_message_get_storage_id(cm) == storage_id) + return linphone_chat_message_ref(cm); + } + return NULL; +} + static ORTP_INLINE LinphoneChatMessage* get_transient_message(LinphoneChatRoom* cr, unsigned int storage_id){ bctbx_list_t* transients = cr->transient_messages; LinphoneChatMessage* chat; @@ -206,10 +217,15 @@ static int callback_all(void *data, int argc, char **argv, char **colName){ static int create_chat_message(void *data, int argc, char **argv, char **colName){ LinphoneChatRoom *cr = (LinphoneChatRoom *)data; unsigned int storage_id = (unsigned int)atoi(argv[0]); + LinphoneChatMessage* new_message; - // check if the message exists in the transient list, in which case we should return that one. - LinphoneChatMessage* new_message = get_transient_message(cr, storage_id); - if( new_message == NULL ){ + /* Check if the message exists in the weak messages list, in which case we should return that one. */ + new_message = get_weak_message(cr, storage_id); + if (new_message == NULL) { + /* Check if the message exists in the transient list, in which case we should return that one. */ + new_message = get_transient_message(cr, storage_id); + } + if (new_message == NULL) { new_message = linphone_chat_room_create_message(cr, argv[4]); if(atoi(argv[3])==LinphoneChatMessageIncoming){ @@ -236,6 +252,9 @@ static int create_chat_message(void *data, int argc, char **argv, char **colName fetch_content_from_database(cr->lc->db, new_message, id); } } + + /* Add the new message to the weak messages list. */ + linphone_chat_room_add_weak_message(cr, new_message); } cr->messages_hist=bctbx_list_prepend(cr->messages_hist,new_message); diff --git a/coreapi/private.h b/coreapi/private.h index e91a43a81..d98e3a340 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -610,6 +610,7 @@ void _linphone_proxy_config_release_ops(LinphoneProxyConfig *obj); /*chat*/ void linphone_chat_room_release(LinphoneChatRoom *cr); +void linphone_chat_room_add_weak_message(LinphoneChatRoom *cr, LinphoneChatMessage *cm); void linphone_chat_message_destroy(LinphoneChatMessage* msg); void linphone_chat_message_update_state(LinphoneChatMessage *msg, LinphoneChatMessageState new_state); void linphone_chat_message_set_state(LinphoneChatMessage *msg, LinphoneChatMessageState state); @@ -701,6 +702,7 @@ struct _LinphoneChatRoom{ LinphoneAddress *peer_url; MSList *messages_hist; MSList *transient_messages; + bctbx_list_t *weak_messages; int unread_count; LinphoneIsComposingState remote_is_composing; LinphoneIsComposingState is_composing; diff --git a/tester/message_tester.c b/tester/message_tester.c index fe6d48e87..e1cc8ca7a 100644 --- a/tester/message_tester.c +++ b/tester/message_tester.c @@ -888,28 +888,31 @@ static void imdn_notifications(void) { LinphoneCoreManager *pauline = linphone_core_manager_new( "pauline_tcp_rc"); LinphoneChatRoom *pauline_chat_room = linphone_core_get_chat_room(pauline->lc, marie->identity); LinphoneChatRoom *marie_chat_room; - LinphoneChatMessage *cm; + LinphoneChatMessage *sent_cm; + LinphoneChatMessage *received_cm; LinphoneChatMessageCbs *cbs; bctbx_list_t *history; - cm = linphone_chat_room_create_message(pauline_chat_room, "Tell me if you get my message"); - cbs = linphone_chat_message_get_callbacks(cm); + sent_cm = linphone_chat_room_create_message(pauline_chat_room, "Tell me if you get my message"); + linphone_chat_message_ref(sent_cm); + cbs = linphone_chat_message_get_callbacks(sent_cm); linphone_chat_message_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed); - linphone_chat_room_send_chat_message(pauline_chat_room, cm); + linphone_chat_room_send_chat_message(pauline_chat_room, sent_cm); BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneMessageReceived, 1)); marie_chat_room = linphone_core_get_chat_room(marie->lc, pauline->identity); history = linphone_chat_room_get_history(marie_chat_room, 1); BC_ASSERT_EQUAL((int)bctbx_list_size(history), 1, int, "%d"); - cm = (LinphoneChatMessage *)bctbx_list_nth_data(history, 0); - BC_ASSERT_PTR_NOT_NULL(cm); - if (cm != NULL) { - linphone_chat_message_notify_delivery(cm); + received_cm = (LinphoneChatMessage *)bctbx_list_nth_data(history, 0); + BC_ASSERT_PTR_NOT_NULL(received_cm); + if (received_cm != NULL) { + linphone_chat_message_notify_delivery(received_cm); BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &pauline->stat.number_of_LinphoneMessageDeliveredToUser, 1)); - linphone_chat_message_notify_display(cm); + linphone_chat_message_notify_display(received_cm); BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &pauline->stat.number_of_LinphoneMessageDisplayed, 1)); bctbx_list_free_with_data(history, (bctbx_list_free_func)linphone_chat_message_unref); } + linphone_chat_message_unref(sent_cm); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); }