From 5d7894e400640430b9d4696e10cd659860e8a6e5 Mon Sep 17 00:00:00 2001 From: Julien Wadel Date: Thu, 28 Jul 2022 20:05:31 +0200 Subject: [PATCH] Create a secure chat room when calling someone with standard chat deactivated. --- .../src/components/call/CallModel.cpp | 45 ++++++++++++++----- .../src/components/call/CallModel.hpp | 6 ++- .../src/components/calls/CallsListModel.cpp | 2 +- .../src/components/calls/CallsListModel.hpp | 2 +- 4 files changed, 40 insertions(+), 15 deletions(-) diff --git a/linphone-app/src/components/call/CallModel.cpp b/linphone-app/src/components/call/CallModel.cpp index e21043c25..0ed57f6a9 100644 --- a/linphone-app/src/components/call/CallModel.cpp +++ b/linphone-app/src/components/call/CallModel.cpp @@ -27,6 +27,7 @@ #include "app/App.hpp" #include "CallListener.hpp" #include "components/calls/CallsListModel.hpp" +#include "components/chat-room/ChatRoomListener.hpp" #include "components/chat-room/ChatRoomModel.hpp" #include "components/conference/ConferenceModel.hpp" #include "components/conferenceInfo/ConferenceInfoModel.hpp" @@ -54,6 +55,10 @@ void CallModel::connectTo(CallListener * listener){ connect(listener, &CallListener::remoteRecording, this, &CallModel::onRemoteRecording); } +void CallModel::connectTo(ChatRoomListener * listener){ + connect(listener, &ChatRoomListener::stateChanged, this, &CallModel::onChatRoomStateChanged); +} + CallModel::CallModel (shared_ptr call){ CoreManager *coreManager = CoreManager::getInstance(); SettingsModel *settings = coreManager->getSettingsModel(); @@ -76,7 +81,8 @@ CallModel::CallModel (shared_ptr call){ }else settings->setCameraMode(settings->getCallCameraMode()); } - + mDelayedCreationChatRoom.first = std::make_shared(); + connectTo(mDelayedCreationChatRoom.first.get()); // Deal with auto-answer. if (!isOutgoing()) { @@ -164,15 +170,20 @@ ContactModel *CallModel::getContactModel() const{ return CoreManager::getInstance()->getContactsListModel()->findContactModelFromSipAddress(cleanedAddress).get(); } -ChatRoomModel * CallModel::getChatRoomModel() const{ +ChatRoomModel * CallModel::getChatRoomModel(){ if(mCall && mCall->getCallLog()->getCallId() != "" && !mCall->getConference()) {// Conference has no chat room yet. auto currentParams = mCall->getCurrentParams(); bool isEncrypted = currentParams->getMediaEncryption() != linphone::MediaEncryption::None; SettingsModel * settingsModel = CoreManager::getInstance()->getSettingsModel(); - + if(mDelayedCreationChatRoom.second){// We already created a chat room. + if( mDelayedCreationChatRoom.second->getState() == linphone::ChatRoom::State::Created) + return CoreManager::getInstance()->getTimelineListModel()->getChatRoomModel(mDelayedCreationChatRoom.second, true).get(); + else// Chat room is not yet created. + return nullptr; + } if( mCall->getChatRoom() && (settingsModel->getSecureChatEnabled() && (!settingsModel->getStandardChatEnabled() || (settingsModel->getStandardChatEnabled() && isEncrypted)) - )){ + )){// Make a secure chat std::shared_ptr core = CoreManager::getInstance()->getCore(); std::shared_ptr dbParams = mCall->getChatRoom()->getCurrentParams(); std::shared_ptr params = core->createDefaultChatRoomParams(); @@ -180,14 +191,14 @@ ChatRoomModel * CallModel::getChatRoomModel() const{ auto callLocalAddress = callLog->getLocalAddress(); std::list> participants; std::shared_ptr chatRoom; -// Copy parameters - params->setBackend(dbParams->getBackend()); - params->setEncryptionBackend(dbParams->getEncryptionBackend()); - params->enableEncryption(dbParams->encryptionEnabled()); +// Copy parameters + params->enableEncryption(true); params->enableGroup(dbParams->groupEnabled()); params->enableRtt(dbParams->rttEnabled()); - params->setSubject(dbParams->getSubject()); - params->enableEncryption(true); + if( dbParams->getSubject() == "") // A linphone::ChatRoomBackend::FlexisipChat need a subject. + params->setSubject("Dummy Subject"); + else + params->setSubject(dbParams->getSubject()); std::list> chatRoomParticipants = mCall->getChatRoom()->getParticipants(); for(auto p : chatRoomParticipants){ participants.push_back(p->getAddress()->clone()); @@ -197,8 +208,13 @@ ChatRoomModel * CallModel::getChatRoomModel() const{ , participants); if(chatRoom) return CoreManager::getInstance()->getTimelineListModel()->getChatRoomModel(chatRoom, true).get(); - } - return CoreManager::getInstance()->getTimelineListModel()->getChatRoomModel(mCall->getChatRoom(), true).get(); + else{// Wait for creation. Secure chat rooms cannot be used before being created. + mDelayedCreationChatRoom.second = CoreManager::getInstance()->getCore()->createChatRoom(params, callLocalAddress, participants);// The result cannot be used. + mDelayedCreationChatRoom.second->addListener(mDelayedCreationChatRoom.first); + return nullptr; + } + }else + return CoreManager::getInstance()->getTimelineListModel()->getChatRoomModel(mCall->getChatRoom(), true).get(); }else return nullptr; } @@ -921,6 +937,11 @@ void CallModel::onRemoteRecording(const std::shared_ptr & call, emit remoteRecordingChanged(recording); } +void CallModel::onChatRoomStateChanged(const std::shared_ptr & chatRoom, linphone::ChatRoom::State newState){ + if(newState == linphone::ChatRoom::State::Created)// A chat room has been created for the call. Warn listeners that the model changed. + emit chatRoomModelChanged(); +} + void CallModel::setRemoteDisplayName(const std::string& name){ mRemoteAddress->setDisplayName(name); if(mCall) { diff --git a/linphone-app/src/components/call/CallModel.hpp b/linphone-app/src/components/call/CallModel.hpp index e8ef2f0d2..c08313cde 100644 --- a/linphone-app/src/components/call/CallModel.hpp +++ b/linphone-app/src/components/call/CallModel.hpp @@ -33,6 +33,7 @@ class CallListener; class ConferenceInfoModel; class ConferenceModel; class ContactModel; +class ChatRoomListener; class ChatRoomModel; class CallModel : public QObject { @@ -126,7 +127,7 @@ public: std::shared_ptr getConferenceAddress () const; ContactModel *getContactModel() const; - ChatRoomModel * getChatRoomModel() const; + ChatRoomModel * getChatRoomModel(); ConferenceModel* getConferenceModel(); ConferenceInfoModel* getConferenceInfoModel(); QSharedPointer getConferenceSharedModel(); @@ -185,6 +186,7 @@ public: std::shared_ptr mCall; std::shared_ptr mCallListener; // This is passed to linpĥone object and must be in shared_ptr + QPair, std::shared_ptr> mDelayedCreationChatRoom; // For secure chat rooms, we need to wait till it is created by keeping a ref and by using alistener. std::shared_ptr mRemoteAddress; std::shared_ptr mMagicSearch; @@ -193,6 +195,7 @@ public slots: void searchReceived(std::list> results); void endCall(); void onRemoteRecording(const std::shared_ptr & call, bool recording); + void onChatRoomStateChanged(const std::shared_ptr & chatRoom, linphone::ChatRoom::State newState); signals: void callErrorChanged (const QString &callError); @@ -297,6 +300,7 @@ public: private: void connectTo(CallListener * listener); + void connectTo(ChatRoomListener * listener); bool mIsInConference = false; diff --git a/linphone-app/src/components/calls/CallsListModel.cpp b/linphone-app/src/components/calls/CallsListModel.cpp index 600b5e016..d6673c8df 100644 --- a/linphone-app/src/components/calls/CallsListModel.cpp +++ b/linphone-app/src/components/calls/CallsListModel.cpp @@ -236,7 +236,7 @@ ChatRoomModel* CallsListModel::createChat (const QString &participantAddress) co return nullptr; } -ChatRoomModel* CallsListModel::createChat (const CallModel * model) const{ +ChatRoomModel* CallsListModel::createChat (CallModel * model){ if(model){ return model->getChatRoomModel(); } diff --git a/linphone-app/src/components/calls/CallsListModel.hpp b/linphone-app/src/components/calls/CallsListModel.hpp index 30f3df3b0..c7ed56ce1 100644 --- a/linphone-app/src/components/calls/CallsListModel.hpp +++ b/linphone-app/src/components/calls/CallsListModel.hpp @@ -49,7 +49,7 @@ public: Q_INVOKABLE void launchVideoCall (const QString &sipAddress, const QString& prepareTransfertAddress = "", const bool& autoSelectAfterCreation = true, QVariantMap options = QVariantMap()) const; Q_INVOKABLE QVariantMap launchChat(const QString &sipAddress, const int& securityLevel) const; Q_INVOKABLE ChatRoomModel* createChat (const QString &participantAddress) const; - Q_INVOKABLE ChatRoomModel* createChat (const CallModel * ) const; + Q_INVOKABLE ChatRoomModel* createChat (CallModel * ); Q_INVOKABLE bool createSecureChat (const QString& subject, const QString &participantAddress) const; QVariantMap createChatRoom(const QString& subject, const int& securityLevel, std::shared_ptr localAddress, const QVariantList& participants, const bool& selectAfterCreation) const;