From 39f72680eae5c7ff8f437eca24bdfb38fb4c43c1 Mon Sep 17 00:00:00 2001 From: Julien Wadel Date: Thu, 27 Oct 2022 13:55:07 +0200 Subject: [PATCH] Fix hidden timelines. Do timeline deletion on SDK callabacks to avoid using deleted objects. From secure chats rooms, forward messages on the secure chat rooms if selected from contacts. Update SDK. --- .../src/components/call/CallModel.cpp | 4 +++- .../src/components/call/CallModel.hpp | 4 ++-- .../src/components/calls/CallsListModel.cpp | 2 +- .../components/chat-room/ChatRoomModel.cpp | 18 +++++++++------ .../components/chat-room/ChatRoomModel.hpp | 4 ++-- .../chat-room/ChatRoomProxyModel.cpp | 2 +- .../src/components/settings/SettingsModel.cpp | 1 - .../sip-addresses/SipAddressesModel.cpp | 6 +++-- .../components/timeline/TimelineListModel.cpp | 22 +++++++++---------- .../ui/modules/Linphone/Chat/Chat.qml | 7 +++--- linphone-sdk | 2 +- 11 files changed, 39 insertions(+), 33 deletions(-) diff --git a/linphone-app/src/components/call/CallModel.cpp b/linphone-app/src/components/call/CallModel.cpp index 666502aab..093d3158d 100644 --- a/linphone-app/src/components/call/CallModel.cpp +++ b/linphone-app/src/components/call/CallModel.cpp @@ -242,7 +242,9 @@ bool CallModel::isConference () const{ // Check status to avoid crash when requesting a conference on an ended call. bool isConf = false; if(mCall){ - isConf = getStatus() != CallStatusEnded && (mCall->getConference() != nullptr || mConferenceInfoModel != nullptr); + // Do not call getConference on Ended status. + isConf = (getStatus() != CallStatusEnded && mCall->getConference() != nullptr) || mConferenceInfoModel != nullptr; + if(!isConf){// Check special cases for Linphone. Having conf-id for a conference URI is not standard. auto remoteAddress = mCall->getRemoteAddress(); if( remoteAddress->getDomain() == Constants::LinphoneDomain){ diff --git a/linphone-app/src/components/call/CallModel.hpp b/linphone-app/src/components/call/CallModel.hpp index 1a3792e7b..7138a000b 100644 --- a/linphone-app/src/components/call/CallModel.hpp +++ b/linphone-app/src/components/call/CallModel.hpp @@ -55,8 +55,8 @@ class CallModel : public QObject { Q_PROPERTY(bool isOutgoing READ isOutgoing CONSTANT) Q_PROPERTY(bool isInConference READ isInConference NOTIFY isInConferenceChanged) - Q_PROPERTY(bool isConference READ isConference CONSTANT) - Q_PROPERTY(bool isOneToOne READ isOneToOne CONSTANT) + Q_PROPERTY(bool isConference READ isConference NOTIFY conferenceInfoModelChanged) + Q_PROPERTY(bool isOneToOne READ isOneToOne NOTIFY conferenceInfoModelChanged) Q_PROPERTY(int duration READ getDuration CONSTANT) // Constants but called with a timer in qml. diff --git a/linphone-app/src/components/calls/CallsListModel.cpp b/linphone-app/src/components/calls/CallsListModel.cpp index e2c50ca14..72c53acc5 100644 --- a/linphone-app/src/components/calls/CallsListModel.cpp +++ b/linphone-app/src/components/calls/CallsListModel.cpp @@ -343,7 +343,7 @@ QVariantMap CallsListModel::createChatRoom(const QString& subject, const int& se initializer->setAdminsData(admins); ChatRoomInitializer::start(initializer); } - timeline = timelineList->getTimeline(chatRoom, ChatRoomModel::isTerminated(chatRoom)); + timeline = timelineList->getTimeline(chatRoom, true); }else{ if(admins.size() > 0){ ChatRoomInitializer::create(chatRoom)->setAdmins(admins); diff --git a/linphone-app/src/components/chat-room/ChatRoomModel.cpp b/linphone-app/src/components/chat-room/ChatRoomModel.cpp index 947c67fa5..56249f197 100644 --- a/linphone-app/src/components/chat-room/ChatRoomModel.cpp +++ b/linphone-app/src/components/chat-room/ChatRoomModel.cpp @@ -107,7 +107,7 @@ void ChatRoomModel::connectTo(ChatRoomListener * listener){ } // ----------------------------------------------------------------------------- -QSharedPointer ChatRoomModel::create(std::shared_ptr chatRoom, const std::list>& callLogs){ +QSharedPointer ChatRoomModel::create(const std::shared_ptr& chatRoom, const std::list>& callLogs){ QSharedPointer model = QSharedPointer::create(chatRoom, callLogs); if(model){ model->mSelf = model; @@ -117,7 +117,7 @@ QSharedPointer ChatRoomModel::create(std::shared_ptr chatRoom, const std::list>& callLogs, QObject * parent) : ProxyListModel(parent){ +ChatRoomModel::ChatRoomModel (const std::shared_ptr& chatRoom, const std::list>& callLogs, QObject * parent) : ProxyListModel(parent){ App::getInstance()->getEngine()->setObjectOwnership(this, QQmlEngine::CppOwnership);// Avoid QML to destroy it when passing by Q_INVOKABLE CoreManager *coreManager = CoreManager::getInstance(); mCoreHandlers = coreManager->getHandlers(); @@ -311,11 +311,11 @@ QString ChatRoomModel::getLocalAddress () const { } QString ChatRoomModel::getFullPeerAddress () const { - return mChatRoom ? Utils::coreStringToAppString(mChatRoom->getPeerAddress()->asString()) : ""; + return mChatRoom && mChatRoom->getPeerAddress() ? Utils::coreStringToAppString(mChatRoom->getPeerAddress()->asString()) : ""; } QString ChatRoomModel::getFullLocalAddress () const { - return mChatRoom ? Utils::coreStringToAppString(mChatRoom->getLocalAddress()->asString()) : ""; + return mChatRoom && mChatRoom->getLocalAddress()? Utils::coreStringToAppString(mChatRoom->getLocalAddress()->asString()) : ""; } QString ChatRoomModel::getConferenceAddress () const { @@ -620,15 +620,14 @@ void ChatRoomModel::markAsToDelete(){ void ChatRoomModel::deleteChatRoom(){ qInfo() << "Deleting ChatRoom : " << getSubject() << ", address=" << getFullPeerAddress(); if(mChatRoom){ - mChatRoom->removeListener(mChatRoomListener); CoreManager::getInstance()->getCore()->deleteChatRoom(mChatRoom); } - emit chatRoomDeleted(); } void ChatRoomModel::leaveChatRoom (){ if(mChatRoom){ - mChatRoom->leave(); + if(!isReadOnly()) + mChatRoom->leave(); if( mChatRoom->getHistorySize() == 0 && mChatRoom->getHistoryEventsSize() == 0) deleteChatRoom(); } @@ -1311,6 +1310,11 @@ void ChatRoomModel::onParticipantAdminStatusChanged(const std::shared_ptr & chatRoom, linphone::ChatRoom::State newState){ updateLastUpdateTime(); emit stateChanged(getState()); + if(newState == linphone::ChatRoom::State::Deleted){ + mChatRoom->removeListener(mChatRoomListener); + mChatRoom = nullptr; + emit chatRoomDeleted(); + } } void ChatRoomModel::onSecurityEvent(const std::shared_ptr & chatRoom, const std::shared_ptr & eventLog){ diff --git a/linphone-app/src/components/chat-room/ChatRoomModel.hpp b/linphone-app/src/components/chat-room/ChatRoomModel.hpp index ec8e82e26..9ec963137 100644 --- a/linphone-app/src/components/chat-room/ChatRoomModel.hpp +++ b/linphone-app/src/components/chat-room/ChatRoomModel.hpp @@ -93,8 +93,8 @@ public: Q_PROPERTY(bool entriesLoading READ isEntriesLoading WRITE setEntriesLoading NOTIFY entriesLoadingChanged) - static QSharedPointer create(std::shared_ptr chatRoom, const std::list>& callLogs = std::list>()); - ChatRoomModel (std::shared_ptr chatRoom, const std::list>& callLogs = std::list>(), QObject * parent = nullptr); + static QSharedPointer create(const std::shared_ptr& chatRoom, const std::list>& callLogs = std::list>()); + ChatRoomModel (const std::shared_ptr& chatRoom, const std::list>& callLogs = std::list>(), QObject * parent = nullptr); ~ChatRoomModel (); diff --git a/linphone-app/src/components/chat-room/ChatRoomProxyModel.cpp b/linphone-app/src/components/chat-room/ChatRoomProxyModel.cpp index ec1b15942..50526b763 100644 --- a/linphone-app/src/components/chat-room/ChatRoomProxyModel.cpp +++ b/linphone-app/src/components/chat-room/ChatRoomProxyModel.cpp @@ -335,7 +335,7 @@ void ChatRoomProxyModel::setChatRoomModel (ChatRoomModel *chatRoomModel){ }else{ if(mIsCall && mChatRoomModel) mChatRoomModel->removeBindingCall(); - mChatRoomModel = nullptr; + mChatRoomModel = nullptr; } } // ----------------------------------------------------------------------------- diff --git a/linphone-app/src/components/settings/SettingsModel.cpp b/linphone-app/src/components/settings/SettingsModel.cpp index d1b4c0018..cbf7d438a 100644 --- a/linphone-app/src/components/settings/SettingsModel.cpp +++ b/linphone-app/src/components/settings/SettingsModel.cpp @@ -69,7 +69,6 @@ SettingsModel::SettingsModel (QObject *parent) : QObject(parent) { connect(coreManager->getAccountSettingsModel(), &AccountSettingsModel::accountSettingsUpdated, this, &SettingsModel::videoConferenceEnabledChanged); connect(coreManager->getAccountSettingsModel(), &AccountSettingsModel::accountSettingsUpdated, this, &SettingsModel::secureChatEnabledChanged); - configureRlsUri(); } diff --git a/linphone-app/src/components/sip-addresses/SipAddressesModel.cpp b/linphone-app/src/components/sip-addresses/SipAddressesModel.cpp index a76cf3d1b..b4b17cc7e 100644 --- a/linphone-app/src/components/sip-addresses/SipAddressesModel.cpp +++ b/linphone-app/src/components/sip-addresses/SipAddressesModel.cpp @@ -455,8 +455,10 @@ void SipAddressesModel::handleMessageCountReset (ChatRoomModel *chatRoomModel) { } void SipAddressesModel::handleMessageSent (const shared_ptr &message) { - const QString peerAddress(Utils::coreStringToAppString(message->getChatRoom()->getPeerAddress()->asStringUriOnly())); - addOrUpdateSipAddress(peerAddress, message); + if(message->getChatRoom() && message->getChatRoom()->getPeerAddress()){ + const QString peerAddress(Utils::coreStringToAppString(message->getChatRoom()->getPeerAddress()->asStringUriOnly())); + addOrUpdateSipAddress(peerAddress, message); + } } void SipAddressesModel::handleIsComposingChanged (const shared_ptr &chatRoom) { diff --git a/linphone-app/src/components/timeline/TimelineListModel.cpp b/linphone-app/src/components/timeline/TimelineListModel.cpp index c9a4f521d..68a26b0b0 100644 --- a/linphone-app/src/components/timeline/TimelineListModel.cpp +++ b/linphone-app/src/components/timeline/TimelineListModel.cpp @@ -71,7 +71,6 @@ TimelineListModel::TimelineListModel(const TimelineListModel* model){ auto newItem = qobject_cast(item)->clone(); connect(newItem.get(), SIGNAL(selectedChanged(bool)), this, SLOT(onSelectedHasChanged(bool))); connect(newItem.get(), &TimelineModel::chatRoomDeleted, this, &TimelineListModel::onChatRoomDeleted); - connect(newItem->getChatRoomModel(), &ChatRoomModel::allEntriesRemoved, this, &TimelineListModel::removeChatRoomModel); mList << newItem; } } @@ -141,7 +140,6 @@ QSharedPointer TimelineListModel::getTimeline(std::shared_ptr model = TimelineModel::create(this, chatRoom); if(model){ connect(model.get(), SIGNAL(selectedChanged(bool)), this, SLOT(onSelectedHasChanged(bool))); - connect(model->getChatRoomModel(), &ChatRoomModel::allEntriesRemoved, this, &TimelineListModel::removeChatRoomModel); add(model); return model; } @@ -189,7 +187,6 @@ QSharedPointer TimelineListModel::getChatRoomModel(std::shared_pt QSharedPointer model = TimelineModel::create(this, chatRoom); if(model){ connect(model.get(), SIGNAL(selectedChanged(bool)), this, SLOT(onSelectedHasChanged(bool))); - connect(model->getChatRoomModel(), &ChatRoomModel::allEntriesRemoved, this, &TimelineListModel::removeChatRoomModel); add(model); return model->mChatRoomModel; } @@ -249,7 +246,7 @@ void TimelineListModel::updateTimelines () { allChatRooms.remove_if([](std::shared_ptr chatRoom){ if( ChatRoomModel::isTerminated(chatRoom) && chatRoom->getUnreadMessagesCount() > 0) chatRoom->markAsRead(); - return !chatRoom->hasCapability((int)linphone::ChatRoomCapabilities::Basic) && chatRoom->getConferenceAddress() && chatRoom->getHistoryEventsSize() == 0; + return chatRoom->getState() == linphone::ChatRoom::State::Deleted || (!chatRoom->hasCapability((int)linphone::ChatRoomCapabilities::Basic) && chatRoom->getConferenceAddress() && chatRoom->getHistoryEventsSize() == 0); }); //Remove no more chat rooms @@ -294,7 +291,6 @@ void TimelineListModel::updateTimelines () { QSharedPointer model = TimelineModel::create(this, dbChatRoom, callLogs); if( model){ connect(model.get(), SIGNAL(selectedChanged(bool)), this, SLOT(onSelectedHasChanged(bool))); - connect(model->getChatRoomModel(), &ChatRoomModel::allEntriesRemoved, this, &TimelineListModel::removeChatRoomModel); add(model); } } @@ -306,12 +302,10 @@ void TimelineListModel::add (QSharedPointer timeline){ auto chatRoomModel = timeline->getChatRoomModel(); auto chatRoom = chatRoomModel->getChatRoom(); connect(timeline.get(), &TimelineModel::chatRoomDeleted, this, &TimelineListModel::onChatRoomDeleted); - if( !chatRoomModel->haveConferenceAddress() || chatRoom->getHistoryEventsSize() != 0) { - connect(chatRoomModel, &ChatRoomModel::lastUpdateTimeChanged, this, &TimelineListModel::updated); - ProxyListModel::add(timeline); - emit layoutChanged(); - emit countChanged(); - } + connect(chatRoomModel, &ChatRoomModel::lastUpdateTimeChanged, this, &TimelineListModel::updated); + ProxyListModel::add(timeline); + emit layoutChanged(); + emit countChanged(); } void TimelineListModel::removeChatRoomModel(QSharedPointer model){ @@ -356,7 +350,6 @@ void TimelineListModel::onChatRoomStateChanged(const std::shared_ptr model = TimelineModel::create(this, chatRoom); if(model){ connect(model.get(), SIGNAL(selectedChanged(bool)), this, SLOT(onSelectedHasChanged(bool))); - connect(model->getChatRoomModel(), &ChatRoomModel::allEntriesRemoved, this, &TimelineListModel::removeChatRoomModel); add(model); } }else if(state == linphone::ChatRoom::State::Deleted || state == linphone::ChatRoom::State::Terminated){ @@ -368,6 +361,11 @@ void TimelineListModel::onChatRoomStateChanged(const std::shared_ptr