mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-17 19:18:06 +00:00
Send delivery notifications when loading chat rooms from DB if needed.
This commit is contained in:
parent
9b0d705ee0
commit
38ea7dc357
8 changed files with 159 additions and 1 deletions
|
|
@ -47,6 +47,8 @@ public:
|
|||
virtual void addTransientEvent (const std::shared_ptr<EventLog> &eventLog) = 0;
|
||||
virtual void removeTransientEvent (const std::shared_ptr<EventLog> &eventLog) = 0;
|
||||
|
||||
virtual void sendDeliveryNotifications () = 0;
|
||||
|
||||
virtual void notifyChatMessageReceived (const std::shared_ptr<ChatMessage> &chatMessage) = 0;
|
||||
virtual void notifyUndecryptableChatMessageReceived (const std::shared_ptr<ChatMessage> &chatMessage) = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ public:
|
|||
|
||||
void sendDeliveryErrorNotification (const std::shared_ptr<ChatMessage> &message, LinphoneReason reason);
|
||||
void sendDeliveryNotification (const std::shared_ptr<ChatMessage> &message);
|
||||
void sendDeliveryNotifications () override;
|
||||
bool sendDisplayNotification (const std::shared_ptr<ChatMessage> &message);
|
||||
|
||||
void notifyChatMessageReceived (const std::shared_ptr<ChatMessage> &chatMessage) override;
|
||||
|
|
|
|||
|
|
@ -153,6 +153,16 @@ void ChatRoomPrivate::sendDeliveryNotification (const shared_ptr<ChatMessage> &m
|
|||
imdnHandler->notifyDelivery(message);
|
||||
}
|
||||
|
||||
void ChatRoomPrivate::sendDeliveryNotifications () {
|
||||
L_Q();
|
||||
LinphoneImNotifPolicy *policy = linphone_core_get_im_notif_policy(q->getCore()->getCCore());
|
||||
if (linphone_im_notif_policy_get_send_imdn_delivered(policy)) {
|
||||
auto messages = q->getCore()->getPrivate()->mainDb->findChatMessagesToBeNotifiedAsDelivered(q->getChatRoomId());
|
||||
for (const auto message : messages)
|
||||
imdnHandler->notifyDelivery(message);
|
||||
}
|
||||
}
|
||||
|
||||
bool ChatRoomPrivate::sendDisplayNotification (const shared_ptr<ChatMessage> &message) {
|
||||
L_Q();
|
||||
LinphoneImNotifPolicy *policy = linphone_core_get_im_notif_policy(q->getCore()->getCCore());
|
||||
|
|
|
|||
|
|
@ -57,6 +57,10 @@ public:
|
|||
chatRoom->getPrivate()->removeTransientEvent(eventLog);
|
||||
}
|
||||
|
||||
inline void sendDeliveryNotifications () override {
|
||||
chatRoom->getPrivate()->sendDeliveryNotifications();
|
||||
}
|
||||
|
||||
inline void notifyChatMessageReceived (const std::shared_ptr<ChatMessage> &chatMessage) override {
|
||||
chatRoom->getPrivate()->notifyChatMessageReceived(chatMessage);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -179,8 +179,10 @@ void CorePrivate::insertChatRoomWithDb (const shared_ptr<AbstractChatRoom> &chat
|
|||
void CorePrivate::loadChatRooms () {
|
||||
chatRooms.clear();
|
||||
chatRoomsById.clear();
|
||||
for (auto &chatRoom : mainDb->getChatRooms())
|
||||
for (auto &chatRoom : mainDb->getChatRooms()) {
|
||||
insertChatRoom(chatRoom);
|
||||
chatRoom->getPrivate()->sendDeliveryNotifications();
|
||||
}
|
||||
}
|
||||
|
||||
void CorePrivate::replaceChatRoom (const shared_ptr<AbstractChatRoom> &replacedChatRoom, const shared_ptr<AbstractChatRoom> &newChatRoom) {
|
||||
|
|
|
|||
|
|
@ -2148,6 +2148,43 @@ list<shared_ptr<ChatMessage>> MainDb::findChatMessages (
|
|||
};
|
||||
}
|
||||
|
||||
list<shared_ptr<ChatMessage>> MainDb::findChatMessagesToBeNotifiedAsDelivered (
|
||||
const ChatRoomId &chatRoomId
|
||||
) const {
|
||||
static const string query = Statements::get(Statements::SelectConferenceEvents) +
|
||||
string(" AND direction = :direction AND state = :state AND delivery_notification_required <> 0");
|
||||
|
||||
DurationLogger durationLogger(
|
||||
"Find chat messages to be notified as delivered: (peer=" + chatRoomId.getPeerAddress().asString() +
|
||||
", local=" + chatRoomId.getLocalAddress().asString() + ")."
|
||||
);
|
||||
|
||||
return L_DB_TRANSACTION {
|
||||
L_D();
|
||||
|
||||
shared_ptr<AbstractChatRoom> chatRoom = d->findChatRoom(chatRoomId);
|
||||
list<shared_ptr<ChatMessage>> chatMessages;
|
||||
if (!chatRoom)
|
||||
return chatMessages;
|
||||
|
||||
const long long &dbChatRoomId = d->selectChatRoomId(chatRoomId);
|
||||
const int &state = int(ChatMessage::State::Delivered);
|
||||
const int &direction = int(ChatMessage::Direction::Incoming);
|
||||
soci::rowset<soci::row> rows = (
|
||||
d->dbSession.getBackendSession()->prepare << query, soci::use(dbChatRoomId), soci::use(direction), soci::use(state)
|
||||
);
|
||||
for (const auto &row : rows) {
|
||||
shared_ptr<EventLog> event = d->selectGenericConferenceEvent(chatRoom, row);
|
||||
if (event) {
|
||||
L_ASSERT(event->getType() == EventLog::Type::ConferenceChatMessage);
|
||||
chatMessages.push_back(static_pointer_cast<ConferenceChatMessageEvent>(event)->getChatMessage());
|
||||
}
|
||||
}
|
||||
|
||||
return chatMessages;
|
||||
};
|
||||
}
|
||||
|
||||
list<shared_ptr<EventLog>> MainDb::getHistory (const ChatRoomId &chatRoomId, int nLast, FilterMask mask) const {
|
||||
return getHistoryRange(chatRoomId, 0, nLast, mask);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -130,6 +130,10 @@ public:
|
|||
const std::string &imdnMessageId
|
||||
) const;
|
||||
|
||||
std::list<std::shared_ptr<ChatMessage>> findChatMessagesToBeNotifiedAsDelivered (
|
||||
const ChatRoomId &chatRoomId
|
||||
) const;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Conference events.
|
||||
// ---------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -3235,6 +3235,103 @@ static void aggregated_imdn_for_group_chat_room_read_while_offline (void) {
|
|||
aggregated_imdn_for_group_chat_room_base(TRUE);
|
||||
}
|
||||
|
||||
static void imdn_sent_from_db_state (void) {
|
||||
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
|
||||
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
|
||||
LinphoneCoreManager *chloe = linphone_core_manager_create("chloe_rc");
|
||||
bctbx_list_t *coresManagerList = NULL;
|
||||
bctbx_list_t *participantsAddresses = NULL;
|
||||
coresManagerList = bctbx_list_append(coresManagerList, marie);
|
||||
coresManagerList = bctbx_list_append(coresManagerList, pauline);
|
||||
coresManagerList = bctbx_list_append(coresManagerList, chloe);
|
||||
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
|
||||
start_core_for_conference(coresManagerList);
|
||||
participantsAddresses = bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
|
||||
participantsAddresses = bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(chloe->lc)));
|
||||
stats initialMarieStats = marie->stat;
|
||||
stats initialPaulineStats = pauline->stat;
|
||||
stats initialChloeStats = chloe->stat;
|
||||
time_t initialTime = ms_time(NULL);
|
||||
|
||||
// Enable IMDN except for Marie
|
||||
linphone_im_notif_policy_clear(linphone_core_get_im_notif_policy(marie->lc));
|
||||
linphone_im_notif_policy_enable_all(linphone_core_get_im_notif_policy(pauline->lc));
|
||||
linphone_im_notif_policy_enable_all(linphone_core_get_im_notif_policy(chloe->lc));
|
||||
|
||||
// Marie creates a new group chat room
|
||||
const char *initialSubject = "Colleagues";
|
||||
LinphoneChatRoom *marieCr = create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject, -1);
|
||||
LinphoneAddress *confAddr = linphone_address_clone(linphone_chat_room_get_conference_address(marieCr));
|
||||
|
||||
// Check that the chat room is correctly created on Pauline's side and that the participants are added
|
||||
LinphoneChatRoom *paulineCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats, confAddr, initialSubject, 2, FALSE);
|
||||
|
||||
// Check that the chat room is correctly created on Chloe's side and that the participants are added
|
||||
LinphoneChatRoom *chloeCr = check_creation_chat_room_client_side(coresList, chloe, &initialChloeStats, confAddr, initialSubject, 2, FALSE);
|
||||
|
||||
// Chloe begins composing a message
|
||||
const char *chloeTextMessage = "Hello";
|
||||
LinphoneChatMessage *chloeMessage = _send_message(chloeCr, chloeTextMessage);
|
||||
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageReceived, initialMarieStats.number_of_LinphoneMessageReceived + 1, 3000));
|
||||
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived + 1, 3000));
|
||||
LinphoneChatMessage *marieLastMsg = marie->stat.last_received_chat_message;
|
||||
if (!BC_ASSERT_PTR_NOT_NULL(marieLastMsg))
|
||||
goto end;
|
||||
BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(marieLastMsg), chloeTextMessage);
|
||||
LinphoneAddress *chloeAddr = linphone_address_new(linphone_core_get_identity(chloe->lc));
|
||||
BC_ASSERT_TRUE(linphone_address_weak_equal(chloeAddr, linphone_chat_message_get_from_address(marieLastMsg)));
|
||||
linphone_address_unref(chloeAddr);
|
||||
|
||||
// Check that the message is not globally marked as delivered to user since Marie do not notify its delivery
|
||||
BC_ASSERT_FALSE(wait_for_list(coresList, &chloe->stat.number_of_LinphoneMessageDeliveredToUser, initialChloeStats.number_of_LinphoneMessageDeliveredToUser + 1, 3000));
|
||||
|
||||
// Restart Marie's core with IMDN enabled so that delivery notification is sent when chat room is loaded from DB
|
||||
coresList = bctbx_list_remove(coresList, marie->lc);
|
||||
linphone_core_manager_reinit(marie);
|
||||
bctbx_list_t *tmpCoresManagerList = bctbx_list_append(NULL, marie);
|
||||
bctbx_list_t *tmpCoresList = init_core_for_conference(tmpCoresManagerList);
|
||||
bctbx_list_free(tmpCoresManagerList);
|
||||
coresList = bctbx_list_concat(coresList, tmpCoresList);
|
||||
linphone_im_notif_policy_enable_all(linphone_core_get_im_notif_policy(marie->lc));
|
||||
linphone_core_manager_start(marie, TRUE);
|
||||
char *marieIdentity = linphone_core_get_device_identity(marie->lc);
|
||||
LinphoneAddress *marieAddr = linphone_address_new(marieIdentity);
|
||||
bctbx_free(marieIdentity);
|
||||
marieCr = linphone_core_find_chat_room(marie->lc, confAddr, marieAddr);
|
||||
linphone_address_unref(marieAddr);
|
||||
linphone_address_unref(confAddr);
|
||||
|
||||
// Check that the message has been delivered to Marie and Pauline
|
||||
BC_ASSERT_TRUE(wait_for_list(coresList, &chloe->stat.number_of_LinphoneMessageDeliveredToUser, initialChloeStats.number_of_LinphoneMessageDeliveredToUser + 1, 3000));
|
||||
BC_ASSERT_PTR_NULL(linphone_chat_message_get_participants_that_have_displayed(chloeMessage));
|
||||
bctbx_list_t *participantsThatReceivedChloeMessage = linphone_chat_message_get_participants_that_have_received(chloeMessage);
|
||||
if (BC_ASSERT_PTR_NOT_NULL(participantsThatReceivedChloeMessage)) {
|
||||
BC_ASSERT_EQUAL((int)bctbx_list_size(participantsThatReceivedChloeMessage), 2, int, "%d");
|
||||
for (bctbx_list_t *item = participantsThatReceivedChloeMessage; item; item = bctbx_list_next(item)) {
|
||||
LinphoneParticipantImdnState *state = (LinphoneParticipantImdnState *)bctbx_list_get_data(item);
|
||||
BC_ASSERT_GREATER(linphone_participant_imdn_state_get_state_change_time(state), initialTime, int, "%d");
|
||||
BC_ASSERT_EQUAL(linphone_participant_imdn_state_get_state(state), LinphoneChatMessageStateDeliveredToUser, int, "%d");
|
||||
BC_ASSERT_PTR_NOT_NULL(linphone_participant_imdn_state_get_participant(state));
|
||||
}
|
||||
bctbx_list_free_with_data(participantsThatReceivedChloeMessage, (bctbx_list_free_func)linphone_participant_imdn_state_unref);
|
||||
}
|
||||
BC_ASSERT_PTR_NULL(linphone_chat_message_get_participants_that_have_not_received(chloeMessage));
|
||||
|
||||
linphone_chat_message_unref(chloeMessage);
|
||||
|
||||
end:
|
||||
// Clean db from chat room
|
||||
linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
|
||||
linphone_core_manager_delete_chat_room(chloe, chloeCr, coresList);
|
||||
linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
|
||||
|
||||
bctbx_list_free(coresList);
|
||||
bctbx_list_free(coresManagerList);
|
||||
linphone_core_manager_destroy(marie);
|
||||
linphone_core_manager_destroy(pauline);
|
||||
linphone_core_manager_destroy(chloe);
|
||||
}
|
||||
|
||||
static void find_one_to_one_chat_room (void) {
|
||||
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
|
||||
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
|
||||
|
|
@ -3423,6 +3520,7 @@ test_t group_chat_tests[] = {
|
|||
TEST_NO_TAG("IMDN for group chat room", imdn_for_group_chat_room),
|
||||
TEST_NO_TAG("Aggregated IMDN for group chat room", aggregated_imdn_for_group_chat_room),
|
||||
TEST_NO_TAG("Aggregated IMDN for group chat room read while offline", aggregated_imdn_for_group_chat_room_read_while_offline),
|
||||
TEST_ONE_TAG("IMDN sent from DB state", imdn_sent_from_db_state, "LeaksMemory"),
|
||||
TEST_NO_TAG("Find one to one chat room", find_one_to_one_chat_room),
|
||||
TEST_NO_TAG("New device after group chat room creation", group_chat_room_new_device_after_creation)
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue