Commit fd58d421 authored by Ronan's avatar Ronan Committed by Ronan

fix(ChatMessage): do not create chat room if it does not exist

parent ee5d1bbb
......@@ -70,6 +70,11 @@ LINPHONE_PUBLIC void linphone_chat_message_set_user_data (LinphoneChatMessage *m
// =============================================================================
/**
* Returns back pointer to #LinphoneCore object.
**/
LINPHONE_PUBLIC LinphoneCore *linphone_chat_message_get_core (const LinphoneChatMessage *msg);
LINPHONE_PUBLIC const char *linphone_chat_message_get_external_body_url (const LinphoneChatMessage *msg);
LINPHONE_PUBLIC void linphone_chat_message_set_external_body_url (LinphoneChatMessage *msg, const char *external_body_url);
......
......@@ -30,10 +30,11 @@
#include "chat/chat-room/chat-room-p.h"
#include "chat/chat-room/real-time-text-chat-room-p.h"
#include "chat/notification/imdn.h"
#include "conference/participant-imdn-state.h"
#include "conference/participant.h"
#include "content/content-type.h"
#include "content/content.h"
#include "conference/participant.h"
#include "conference/participant-imdn-state.h"
#include "core/core-p.h"
// =============================================================================
......@@ -111,6 +112,10 @@ LinphoneChatMessageCbs *linphone_chat_message_get_callbacks(const LinphoneChatMe
// Getter and setters
// =============================================================================
LINPHONE_PUBLIC LinphoneCore *linphone_chat_message_get_core (const LinphoneChatMessage *msg) {
return L_GET_CPP_PTR_FROM_C_OBJECT(msg)->getCore()->getCCore();
}
LinphoneChatRoom *linphone_chat_message_get_chat_room (const LinphoneChatMessage *msg) {
return L_GET_C_BACK_PTR(L_GET_CPP_PTR_FROM_C_OBJECT(msg)->getChatRoom());
}
......
......@@ -211,7 +211,6 @@ private:
// Do not expose.
std::weak_ptr<AbstractChatRoom> chatRoom;
ConferenceId conferenceId;
IdentityAddress fromAddress;
IdentityAddress toAddress;
......
......@@ -428,7 +428,7 @@ std::string ChatMessagePrivate::createFakeFileTransferFromUrl(const std::string
void ChatMessagePrivate::setChatRoom (const shared_ptr<AbstractChatRoom> &cr) {
chatRoom = cr;
conferenceId = cr->getConferenceId();
const ConferenceId &conferenceId(cr->getConferenceId());
if (direction == ChatMessage::Direction::Outgoing) {
fromAddress = conferenceId.getLocalAddress();
toAddress = conferenceId.getPeerAddress();
......@@ -627,6 +627,10 @@ LinphoneReason ChatMessagePrivate::receive () {
void ChatMessagePrivate::send () {
L_Q();
shared_ptr<AbstractChatRoom> chatRoom(q->getChatRoom());
if (!chatRoom) return;
SalOp *op = salOp;
LinphoneCall *lcall = nullptr;
int errorCode = 0;
......@@ -700,7 +704,7 @@ void ChatMessagePrivate::send () {
if (applyModifiers) {
// Do not multipart or encapsulate with CPIM in an old ChatRoom to maintain backward compatibility
if (q->getChatRoom()->canHandleMultipart()) {
if (chatRoom->canHandleMultipart()) {
if ((currentSendStep &ChatMessagePrivate::Step::Multipart) == ChatMessagePrivate::Step::Multipart) {
lInfo() << "Multipart step already done, skipping";
} else {
......@@ -712,7 +716,7 @@ void ChatMessagePrivate::send () {
}
}
if (q->getChatRoom()->canHandleCpim()) {
if (chatRoom->canHandleCpim()) {
if ((currentSendStep &ChatMessagePrivate::Step::Cpim) == ChatMessagePrivate::Step::Cpim) {
lInfo() << "Cpim step already done, skipping";
} else {
......@@ -815,22 +819,28 @@ void ChatMessagePrivate::storeInDb () {
if (dbKey.isValid()) {
updateInDb();
} else {
shared_ptr<EventLog> eventLog = make_shared<ConferenceChatMessageEvent>(time, q->getSharedFromThis());
return;
}
// Avoid transaction in transaction if contents are not loaded.
loadContentsFromDatabase();
q->getChatRoom()->getPrivate()->addEvent(eventLog);
shared_ptr<EventLog> eventLog = make_shared<ConferenceChatMessageEvent>(time, q->getSharedFromThis());
if (direction == ChatMessage::Direction::Incoming) {
if (hasFileTransferContent()) {
// Keep the event in the transient list, message storage can be updated in near future
q->getChatRoom()->getPrivate()->addTransientEvent(eventLog);
}
} else {
// Keep event in transient to be able to store in database state changes
q->getChatRoom()->getPrivate()->addTransientEvent(eventLog);
// Avoid transaction in transaction if contents are not loaded.
loadContentsFromDatabase();
shared_ptr<AbstractChatRoom> chatRoom(q->getChatRoom());
if (!chatRoom) return;
AbstractChatRoomPrivate *dChatRoom = chatRoom->getPrivate();
dChatRoom->addEvent(eventLog);
if (direction == ChatMessage::Direction::Incoming) {
if (hasFileTransferContent()) {
// Keep the event in the transient list, message storage can be updated in near future
dChatRoom->addTransientEvent(eventLog);
}
} else {
// Keep event in transient to be able to store in database state changes
dChatRoom->addTransientEvent(eventLog);
}
}
......@@ -906,14 +916,9 @@ ChatMessage::~ChatMessage () {
shared_ptr<AbstractChatRoom> ChatMessage::getChatRoom () const {
L_D();
shared_ptr<AbstractChatRoom> chatRoom = d->chatRoom.lock();
if (!chatRoom) {
chatRoom = getCore()->getOrCreateBasicChatRoom(d->conferenceId);
if (!chatRoom) {
lError() << "Unable to get valid chat room instance.";
throw logic_error("Unable to get chat room of chat message.");
}
}
shared_ptr<AbstractChatRoom> chatRoom(d->chatRoom.lock());
if (!chatRoom)
lError() << "Unable to get valid chat room instance.";
return chatRoom;
}
......
......@@ -518,6 +518,7 @@ shared_ptr<EventLog> MainDbPrivate::selectGenericConferenceEvent (
const shared_ptr<AbstractChatRoom> &chatRoom,
const soci::row &row
) const {
L_ASSERT(chatRoom);
EventLog::Type type = EventLog::Type(row.get<int>(1));
if (type == EventLog::Type::ConferenceChatMessage) {
long long eventId = getConferenceEventIdFromRow(row);
......
......@@ -28,6 +28,10 @@ using namespace std;
LINPHONE_BEGIN_NAMESPACE
static inline ConferenceId getSafeConferenceId (const shared_ptr<const AbstractChatRoom> chatRoom) {
return chatRoom ? chatRoom->getConferenceId() : ConferenceId();
}
// -----------------------------------------------------------------------------
class ConferenceChatMessageEventPrivate : public ConferenceEventPrivate {
......@@ -44,7 +48,7 @@ ConferenceChatMessageEvent::ConferenceChatMessageEvent (
*new ConferenceChatMessageEventPrivate,
EventLog::Type::ConferenceChatMessage,
creationTime,
chatMessage->getChatRoom()->getConferenceId()
getSafeConferenceId(chatMessage->getChatRoom())
) {
L_D();
L_ASSERT(chatMessage);
......
......@@ -84,12 +84,12 @@ void file_transfer_received(LinphoneChatMessage *msg, const LinphoneContent* con
file = fopen(receive_file,"wb");
linphone_chat_message_set_user_data(msg,(void*)file); /*store fd for next chunks*/
}
file = (FILE*)linphone_chat_message_get_user_data(msg);
BC_ASSERT_PTR_NOT_NULL(file);
if (linphone_buffer_is_empty(buffer)) { /* tranfer complete */
struct stat st;
linphone_chat_message_set_user_data(msg, NULL);
fclose(file);
BC_ASSERT_TRUE(stat(receive_file, &st)==0);
......@@ -138,19 +138,22 @@ LinphoneBuffer * tester_file_transfer_send(LinphoneChatMessage *msg, const Linph
* function invoked to report file transfer progress.
* */
void file_transfer_progress_indication(LinphoneChatMessage *msg, const LinphoneContent* content, size_t offset, size_t total) {
LinphoneChatRoom *cr = linphone_chat_message_get_chat_room(msg);
LinphoneCore *lc = linphone_chat_room_get_core(cr);
const LinphoneAddress* from_address = linphone_chat_message_get_from_address(msg);
const LinphoneAddress* to_address = linphone_chat_message_get_to_address(msg);
char *address = linphone_chat_message_is_outgoing(msg)?linphone_address_as_string(to_address):linphone_address_as_string(from_address);
stats* counters = get_stats(lc);
const LinphoneAddress *from_address = linphone_chat_message_get_from_address(msg);
const LinphoneAddress *to_address = linphone_chat_message_get_to_address(msg);
int progress = (int)((offset * 100)/total);
ms_message(" File transfer [%d%%] %s of type [%s/%s] %s [%s] \n", progress
,(linphone_chat_message_is_outgoing(msg)?"sent":"received")
, linphone_content_get_type(content)
, linphone_content_get_subtype(content)
,(linphone_chat_message_is_outgoing(msg)?"to":"from")
, address);
LinphoneCore *lc = linphone_chat_message_get_core(msg);
stats *counters = get_stats(lc);
char *address = linphone_address_as_string(linphone_chat_message_is_outgoing(msg) ? to_address : from_address);
bctbx_message(
"File transfer [%d%%] %s of type [%s/%s] %s [%s] \n",
progress,
linphone_chat_message_is_outgoing(msg) ? "sent" : "received",
linphone_content_get_type(content),
linphone_content_get_subtype(content),
linphone_chat_message_is_outgoing(msg) ? "to" : "from",
address
);
counters->progress_of_LinphoneFileTransfer = progress;
if (progress == 100) {
counters->number_of_LinphoneFileTransferDownloadSuccessful++;
......@@ -172,9 +175,8 @@ void liblinphone_tester_chat_message_state_change(LinphoneChatMessage* msg,Linph
}
void liblinphone_tester_chat_message_msg_state_changed(LinphoneChatMessage *msg, LinphoneChatMessageState state) {
LinphoneChatRoom *cr = linphone_chat_message_get_chat_room(msg);
LinphoneCore *lc = linphone_chat_room_get_core(cr);
stats* counters = get_stats(lc);
LinphoneCore *lc = linphone_chat_message_get_core(msg);
stats *counters = get_stats(lc);
switch (state) {
case LinphoneChatMessageStateIdle:
return;
......@@ -1728,7 +1730,7 @@ static void file_transfer_not_sent_if_invalid_url(void) {
linphone_core_manager_destroy(marie);
}
void file_transfer_io_error_base(char *server_url, bool_t destroy_room) {
void file_transfer_io_error_base(char *server_url) {
LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc");
LinphoneChatRoom *chatroom = linphone_core_get_chat_room_from_uri(marie->lc, "<sip:Jehan@sip.linphone.org>");
LinphoneChatMessage *msg = create_message_from_sintel_trailer(chatroom);
......@@ -1737,26 +1739,34 @@ void file_transfer_io_error_base(char *server_url, bool_t destroy_room) {
linphone_core_set_file_transfer_server(marie->lc, server_url);
linphone_chat_message_send(msg);
BC_ASSERT_TRUE(wait_for_until(marie->lc, NULL, &marie->stat.number_of_LinphoneMessageInProgress, 1, 1000));
if (destroy_room) {
linphone_core_delete_chat_room(marie->lc, chatroom);
BC_ASSERT_TRUE(wait_for_until(marie->lc, NULL, &marie->stat.number_of_LinphoneMessageNotDelivered, 1, 1000));
} else {
BC_ASSERT_TRUE(wait_for_until(marie->lc, NULL, &marie->stat.number_of_LinphoneMessageNotDelivered, 1, 3000));
}
BC_ASSERT_TRUE(wait_for_until(marie->lc, NULL, &marie->stat.number_of_LinphoneMessageNotDelivered, 1, 3000));
linphone_chat_message_unref(msg);
linphone_core_manager_destroy(marie);
}
static void file_transfer_not_sent_if_host_not_found(void) {
file_transfer_io_error_base("https://not-existing-url.com", FALSE);
file_transfer_io_error_base("https://not-existing-url.com");
}
static void file_transfer_not_sent_if_url_moved_permanently(void) {
file_transfer_io_error_base("http://linphone.org/toto.php", FALSE);
file_transfer_io_error_base("http://linphone.org/toto.php");
}
static void file_transfer_io_error_after_destroying_chatroom(void) {
file_transfer_io_error_base("https://www.linphone.org:444/lft.php", TRUE);
static void file_transfer_success_after_destroying_chatroom(void) {
LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc");
LinphoneChatRoom *chatroom = linphone_core_get_chat_room_from_uri(marie->lc, "<sip:Jehan@sip.linphone.org>");
LinphoneChatMessage *msg = create_message_from_sintel_trailer(chatroom);
linphone_chat_message_cbs_set_msg_state_changed(
linphone_chat_message_get_callbacks(msg),
liblinphone_tester_chat_message_msg_state_changed
);
linphone_core_set_file_transfer_server(marie->lc, "https://www.linphone.org:444/lft.php");
linphone_chat_message_send(msg);
BC_ASSERT_TRUE(wait_for_until(marie->lc, NULL, &marie->stat.number_of_LinphoneMessageInProgress, 1, 1000));
linphone_core_delete_chat_room(marie->lc, chatroom);
BC_ASSERT_TRUE(wait_for_until(marie->lc, NULL, &marie->stat.number_of_LinphoneMessageDisplayed, 1, 3000));
linphone_chat_message_unref(msg);
linphone_core_manager_destroy(marie);
}
static void real_time_text(
......@@ -1845,7 +1855,7 @@ static void real_time_text(
const char* message = "Be l3l";
size_t i;
LinphoneChatMessage* rtt_message = linphone_chat_room_create_message(pauline_chat_room,NULL);
for (i = 0; i < strlen(message); i++) {
BC_ASSERT_FALSE(linphone_chat_message_put_char(rtt_message, message[i]));
......@@ -2182,7 +2192,7 @@ static void real_time_text_copy_paste(void) {
const char* message = "Be l3l";
size_t i;
LinphoneChatMessage* rtt_message = linphone_chat_room_create_message(pauline_chat_room,NULL);
for (i = 1; i <= strlen(message); i++) {
linphone_chat_message_put_char(rtt_message, message[i-1]);
......@@ -2582,7 +2592,7 @@ test_t message_tests[] = {
TEST_NO_TAG("Info message with body", info_message_with_body),
TEST_NO_TAG("Crash during file transfer", crash_during_file_transfer),
TEST_NO_TAG("Text status after destroying chat room", text_status_after_destroying_chat_room),
TEST_NO_TAG("Transfer io error after destroying chatroom", file_transfer_io_error_after_destroying_chatroom),
TEST_NO_TAG("Transfer success after destroying chatroom", file_transfer_success_after_destroying_chatroom),
TEST_NO_TAG("Migration from messages db", migration_from_messages_db)
};
......
......@@ -33,6 +33,7 @@ import metaname
CORE_ACCESSOR_LIST = [
'Call',
'ChatMessage',
'ChatRoom',
'Event',
'Friend',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment