From 9e4d65a5334f839cfdf52cb3a471e0fc9b231323 Mon Sep 17 00:00:00 2001 From: Gaelle Braud Date: Wed, 15 Apr 2026 16:39:54 +0200 Subject: [PATCH] fix perf issue #LINQT-2491) start by looking for chat in list instead of recreating a chatcore for every event do not create event log core if not handled --- Linphone/core/chat/ChatCore.cpp | 9 ++-- Linphone/core/chat/ChatList.cpp | 47 +++++++++++++-------- Linphone/core/chat/ChatList.hpp | 1 + Linphone/core/chat/message/EventLogCore.cpp | 46 ++++++++++++++++++++ Linphone/core/chat/message/EventLogCore.hpp | 3 ++ Linphone/core/notifier/Notifier.cpp | 7 ++- Linphone/tool/Utils.cpp | 42 +++++++++++++++--- 7 files changed, 127 insertions(+), 28 deletions(-) diff --git a/Linphone/core/chat/ChatCore.cpp b/Linphone/core/chat/ChatCore.cpp index a5a838629..841a0d22a 100644 --- a/Linphone/core/chat/ChatCore.cpp +++ b/Linphone/core/chat/ChatCore.cpp @@ -212,12 +212,12 @@ void ChatCore::setSelf(const QSharedPointer &me) { const std::shared_ptr &eventLog) { if (mChatModel->getMonitor() != chatRoom) return; if (!eventLog) return; - lDebug() << log().arg("EVENT LOG RECEIVED IN CHATROOM") << this << mChatModel->getTitle(); - auto event = EventLogCore::create(eventLog, chatRoom); - if (event->isHandled()) { + if (EventLogCore::isEventHandled(eventLog, chatRoom)) { + lDebug() << log().arg("EVENT LOG RECEIVED IN CHATROOM") << this << mChatModel->getTitle(); + auto event = EventLogCore::create(eventLog, chatRoom); mChatModelConnection->invokeToCore([this, event]() { emit eventsInserted({event}); }); } - mChatModelConnection->invokeToCore([this, event]() { emit lUpdateLastUpdatedTime(); }); + mChatModelConnection->invokeToCore([this]() { emit lUpdateLastUpdatedTime(); }); }); // Chat messages @@ -322,6 +322,7 @@ void ChatCore::setSelf(const QSharedPointer &me) { mChatModelConnection->makeConnectToModel( &ChatModel::chatMessageSending, [this](const std::shared_ptr &chatRoom, const std::shared_ptr &eventLog) { + lInfo() << "Chat message sending in chatroom" << this << mChatModel->getTitle(); auto event = EventLogCore::create(eventLog, chatRoom); mChatModelConnection->invokeToCore([this, event]() { emit eventsInserted({event}); }); }); diff --git a/Linphone/core/chat/ChatList.cpp b/Linphone/core/chat/ChatList.cpp index b7b7b4a28..623696f85 100644 --- a/Linphone/core/chat/ChatList.cpp +++ b/Linphone/core/chat/ChatList.cpp @@ -116,6 +116,11 @@ void ChatList::setSelf(QSharedPointer me) { auto currentAccount = CoreModel::getInstance()->getCore()->getDefaultAccount(); if (!currentAccount) { mModelConnection->invokeToCore([this, chats]() { + for (auto &chat : getSharedList()) { + if (chat) { + disconnectItem(chat); + } + } beginResetModel(); mList.clear(); endResetModel(); @@ -137,13 +142,13 @@ void ChatList::setSelf(QSharedPointer me) { } mModelConnection->invokeToCore([this, chats]() { mustBeInMainThread(getClassName()); - beginResetModel(); - mList.clear(); for (auto &chat : getSharedList()) { if (chat) { disconnectItem(chat); } } + beginResetModel(); + mList.clear(); for (auto &chat : *chats) { connectItem(chat); mList.append(chat); @@ -184,8 +189,15 @@ void ChatList::setSelf(QSharedPointer me) { lInfo() << log().arg("Chat room to add does not match the current filter, return"); return; } - auto chatCore = ChatCore::create(room); - mModelConnection->invokeToCore([this, chatCore, sendAddSignal] { addChatInList(chatCore, sendAddSignal); }); + auto identifier = Utils::coreStringToAppString(room->getIdentifier()); + auto chatList = getSharedList(); + auto it = std::find_if(chatList.begin(), chatList.end(), [identifier](const QSharedPointer item) { + return item && item->getIdentifier() == identifier; + }); + if (it == chatList.end()) { + auto chatCore = ChatCore::create(room); + mModelConnection->invokeToCore([this, chatCore, sendAddSignal] { addChatInList(chatCore, sendAddSignal); }); + } }; mModelConnection->makeConnectToModel( &CoreModel::messageReceived, @@ -239,26 +251,27 @@ int ChatList::findChatIndex(ChatGui *chatGui) { return it == chatList.end() ? -1 : std::distance(chatList.begin(), it); } +QSharedPointer ChatList::findChatById(const QString &id) { + auto chatList = getSharedList(); + auto it = std::find_if(chatList.begin(), chatList.end(), + [id](const QSharedPointer item) { return item->getIdentifier() == id; }); + return it == chatList.end() ? nullptr : *it; +} + bool ChatList::addChatInList(QSharedPointer chatCore, bool emitAddSignal) { mustBeInMainThread(log().arg(Q_FUNC_INFO)); if (chatCore->getIdentifier().isEmpty()) { lWarning() << "ChatRoom with invalid identifier cannot be added to the list, return"; return false; } - auto chatList = getSharedList(); - auto it = std::find_if(chatList.begin(), chatList.end(), [chatCore](const QSharedPointer item) { - return item && chatCore && item->getIdentifier() == chatCore->getIdentifier(); - }); - if (it == chatList.end()) { - connectItem(chatCore); - lInfo() << "Add ChatRoom" << chatCore->getTitle(); - add(chatCore); - if (emitAddSignal) { - CoreModel::getInstance()->mChatRoomBeingCreated = nullptr; - emit chatAdded(chatCore); - } - return true; + connectItem(chatCore); + lInfo() << "Add ChatRoom" << chatCore->getTitle(); + add(chatCore); + if (emitAddSignal) { + CoreModel::getInstance()->mChatRoomBeingCreated = nullptr; + emit chatAdded(chatCore); } + return true; return false; } diff --git a/Linphone/core/chat/ChatList.hpp b/Linphone/core/chat/ChatList.hpp index d523c03a7..25dcfc75a 100644 --- a/Linphone/core/chat/ChatList.hpp +++ b/Linphone/core/chat/ChatList.hpp @@ -43,6 +43,7 @@ public: void disconnectItem(QSharedPointer chat); int findChatIndex(ChatGui *chat); + QSharedPointer findChatById(const QString &id); bool addChatInList(QSharedPointer chatCore, bool emitAddSignal); virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; diff --git a/Linphone/core/chat/message/EventLogCore.cpp b/Linphone/core/chat/message/EventLogCore.cpp index 8a67a07b5..3f5fde620 100644 --- a/Linphone/core/chat/message/EventLogCore.cpp +++ b/Linphone/core/chat/message/EventLogCore.cpp @@ -171,3 +171,49 @@ void EventLogCore::computeEvent(const std::shared_ptr mHandled = false; } } + +bool EventLogCore::isEventHandled(const std::shared_ptr &eventLog, + const std::shared_ptr &chatRoom) { + mustBeInLinphoneThread("EventLogCore::isEventHandled"); + auto handled = true; + auto participantAddress = eventLog->getParticipantAddress() ? eventLog->getParticipantAddress() : nullptr; + + switch (eventLog->getType()) { + case linphone::EventLog::Type::ConferenceCreated: + if (chatRoom->hasCapability((int)linphone::ChatRoom::Capabilities::OneToOne) || + !chatRoom->hasCapability((int)linphone::ChatRoom::Capabilities::Conference)) + handled = false; + break; + case linphone::EventLog::Type::ConferenceTerminated: + if (chatRoom->hasCapability((int)linphone::ChatRoom::Capabilities::OneToOne) || + !chatRoom->hasCapability((int)linphone::ChatRoom::Capabilities::Conference)) + handled = false; + break; + case linphone::EventLog::Type::ConferenceParticipantAdded: + break; + case linphone::EventLog::Type::ConferenceParticipantRemoved: + break; + case linphone::EventLog::Type::ConferenceSecurityEvent: { + if (eventLog->getSecurityEventType() != linphone::EventLog::SecurityEventType::SecurityLevelDowngraded) { + handled = false; + } + break; + } + case linphone::EventLog::Type::ConferenceEphemeralMessageEnabled: + break; + case linphone::EventLog::Type::ConferenceEphemeralMessageLifetimeChanged: + handled = eventLog->getEphemeralMessageLifetime() != 0; // Disabled is sent in case of 0. + break; + case linphone::EventLog::Type::ConferenceEphemeralMessageDisabled: + break; + case linphone::EventLog::Type::ConferenceSubjectChanged: + break; + case linphone::EventLog::Type::ConferenceParticipantSetAdmin: + break; + case linphone::EventLog::Type::ConferenceParticipantUnsetAdmin: + break; + default: + handled = false; + } + return handled; +} \ No newline at end of file diff --git a/Linphone/core/chat/message/EventLogCore.hpp b/Linphone/core/chat/message/EventLogCore.hpp index 0bf8ae5fd..08f0e2861 100644 --- a/Linphone/core/chat/message/EventLogCore.hpp +++ b/Linphone/core/chat/message/EventLogCore.hpp @@ -73,6 +73,9 @@ public: std::shared_ptr getModel() const; + static bool isEventHandled(const std::shared_ptr &eventLog, + const std::shared_ptr &chatRoom); + private: DECLARE_ABSTRACT_OBJECT QString mEventId; diff --git a/Linphone/core/notifier/Notifier.cpp b/Linphone/core/notifier/Notifier.cpp index 65921e3d7..911860d9e 100644 --- a/Linphone/core/notifier/Notifier.cpp +++ b/Linphone/core/notifier/Notifier.cpp @@ -461,7 +461,12 @@ void Notifier::notifyReceivedMessages(const std::shared_ptr } } - auto chatCore = ChatCore::create(room); + auto chatCore = + App::getInstance()->getChatList()->findChatById(Utils::coreStringToAppString(room->getIdentifier())); + if (!chatCore) { + lWarning() << "chat was not found in chat list, create one"; + chatCore = ChatCore::create(room); + } App::postCoreAsync([this, txt, chatCore, remoteAddress]() { mustBeInMainThread(getClassName()); diff --git a/Linphone/tool/Utils.cpp b/Linphone/tool/Utils.cpp index 0960c6b00..62bda393f 100644 --- a/Linphone/tool/Utils.cpp +++ b/Linphone/tool/Utils.cpp @@ -1630,7 +1630,12 @@ VariantObject *Utils::getCurrentCallChat(CallGui *call) { if (!callModel) return QVariant(); auto linphoneChatRoom = ToolModel::lookupCurrentCallChat(callModel); if (linphoneChatRoom) { - auto chatCore = ChatCore::create(linphoneChatRoom); + auto chatCore = App::getInstance()->getChatList()->findChatById( + Utils::coreStringToAppString(linphoneChatRoom->getIdentifier())); + if (!chatCore) { + lWarning() << "Utils::getCurrentCallChat : chat was not found in chat list, create one"; + chatCore = ChatCore::create(linphoneChatRoom); + } return chatCore ? QVariant::fromValue(new ChatGui(chatCore)) : QVariant(); } else { // Only try to create chatroom if 1-1 call @@ -1641,7 +1646,12 @@ VariantObject *Utils::getCurrentCallChat(CallGui *call) { if (linphoneChatRoom != nullptr) { lInfo() << "[Utils] Chatroom created with" << callModel->getRemoteAddress()->asStringUriOnly(); auto id = linphoneChatRoom->getIdentifier(); - auto chatCore = ChatCore::create(linphoneChatRoom); + auto chatCore = App::getInstance()->getChatList()->findChatById( + Utils::coreStringToAppString(linphoneChatRoom->getIdentifier())); + if (!chatCore) { + lWarning() << "Utils::getCurrentCallChat : chat was not found in chat list, create one"; + chatCore = ChatCore::create(linphoneChatRoom); + } return chatCore ? QVariant::fromValue(new ChatGui(chatCore)) : QVariant(); } else { lWarning() << "[Utils] Failed to create 1-1 conversation with" @@ -1663,14 +1673,24 @@ VariantObject *Utils::getChatForAddress(QString address) { linAddr->clean(); auto linphoneChatRoom = ToolModel::lookupChatForAddress(linAddr); if (linphoneChatRoom) { - auto chatCore = ChatCore::create(linphoneChatRoom); + auto chatCore = App::getInstance()->getChatList()->findChatById( + Utils::coreStringToAppString(linphoneChatRoom->getIdentifier())); + if (!chatCore) { + lWarning() << "Utils::getChatForAddress : chat was not found in chat list, create one"; + chatCore = ChatCore::create(linphoneChatRoom); + } return chatCore ? QVariant::fromValue(new ChatGui(chatCore)) : QVariant(); } else { lInfo() << "[Utils] Did not find existing chat room, create one"; linphoneChatRoom = ToolModel::createChatForAddress(linAddr); if (linphoneChatRoom != nullptr) { lInfo() << "[Utils] Chatroom created with" << linAddr->asStringUriOnly(); - auto chatCore = ChatCore::create(linphoneChatRoom); + auto chatCore = App::getInstance()->getChatList()->findChatById( + Utils::coreStringToAppString(linphoneChatRoom->getIdentifier())); + if (!chatCore) { + lWarning() << "Utils::getChatForAddress : chat was not found in chat list, create one"; + chatCore = ChatCore::create(linphoneChatRoom); + } return chatCore ? QVariant::fromValue(new ChatGui(chatCore)) : QVariant(); } else { lWarning() << "[Utils] Failed to create 1-1 conversation with" << linAddr->asStringUriOnly() << "!"; @@ -1700,7 +1720,12 @@ VariantObject *Utils::createGroupChat(QString subject, QStringList participantAd } auto linphoneChatRoom = ToolModel::createGroupChatRoom(subject, addresses); if (linphoneChatRoom) { - auto chatCore = ChatCore::create(linphoneChatRoom); + auto chatCore = App::getInstance()->getChatList()->findChatById( + Utils::coreStringToAppString(linphoneChatRoom->getIdentifier())); + if (!chatCore) { + lWarning() << "Utils::createGroupChat : chat was not found in chat list, create one"; + chatCore = ChatCore::create(linphoneChatRoom); + } return chatCore ? QVariant::fromValue(new ChatGui(chatCore)) : QVariant(); } else { return QVariant(); @@ -1745,7 +1770,12 @@ VariantObject *Utils::getChatForCallLog(CallHistoryGui *callLog) { if (!model) return QVariant(); auto chatRoom = model->getChatRoom(); if (!chatRoom) return QVariant(); - auto chatCore = ChatCore::create(chatRoom); + auto chatCore = + App::getInstance()->getChatList()->findChatById(Utils::coreStringToAppString(chatRoom->getIdentifier())); + if (!chatCore) { + lWarning() << "Utils::getChatForCallLog : chat was not found in chat list, create one"; + chatCore = ChatCore::create(chatRoom); + } return chatCore ? QVariant::fromValue(new ChatGui(chatCore)) : QVariant(); }); data->requestValue();