Store weak references of chat messages in the chat room to be able to returned the same LinphoneChatMessage object to the application.

This commit is contained in:
Ghislain MARY 2016-12-13 16:09:12 +01:00
parent 410f5b9e1c
commit 7889b0610b
4 changed files with 50 additions and 12 deletions

View file

@ -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);
}
}

View file

@ -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);

View file

@ -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;

View file

@ -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);
}