From ea4f1625d178c277890386ba88848fa9dfbeb35e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Blin?= <sebastien.blin@savoirfairelinux.com> Date: Fri, 26 Jul 2019 12:01:18 -0400 Subject: [PATCH] newcallmodel: improve joinCalls Allow calls across several account to be joinable. Change-Id: Id11b2dcb556ad13be73a2a3d58563f42e09bc410 --- src/api/lrc.h | 17 +++++++- src/conversationmodel.cpp | 22 ++++++++++- src/lrc.cpp | 36 +++++++++++++++++ src/newcallmodel.cpp | 83 ++++++++++++++++++++++++++++++++------- 4 files changed, 141 insertions(+), 17 deletions(-) diff --git a/src/api/lrc.h b/src/api/lrc.h index aec00d77..f11c94d8 100644 --- a/src/api/lrc.h +++ b/src/api/lrc.h @@ -91,10 +91,25 @@ public: void subscribeToDebugReceived(); /** - * Helper: get call list from daemon + * Helper: get active call list from daemon */ static std::vector<std::string> activeCalls(); + /** + * Helper: get call list from daemon + */ + static std::vector<std::string> getCalls(); + + /** + * Helper: get conference list from daemon + */ + static std::vector<std::string> getConferences(); + + /** + * Helper: get subcalls list for a conference from daemon + */ + static std::vector<std::string> getConferenceSubcalls(const std::string& id); + private: std::unique_ptr<LrcPimpl> lrcPimpl_; }; diff --git a/src/conversationmodel.cpp b/src/conversationmodel.cpp index 918e1b71..a8d406b7 100644 --- a/src/conversationmodel.cpp +++ b/src/conversationmodel.cpp @@ -1510,7 +1510,25 @@ ConversationModelPimpl::slotCallStatusChanged(const std::string& callId, int cod return conversation.callId == callId; }); - if (i == conversations.end()) return; + if (i == conversations.end()) { + // In this case, the user didn't pass through placeCall + // This means that a participant was invited to a call + // or a call was placed via dbus. + // We have to update the model + try { + auto call = linked.owner.callModel->getCall(callId); + for (auto& conversation: conversations) { + if (conversation.participants.front() == call.peerUri) { + conversation.callId = callId; + dirtyConversations = {true, true}; + emit linked.conversationUpdated(conversation.uid); + } + } + } catch (std::out_of_range& e) { + qDebug() << "ConversationModelPimpl::slotCallStatusChanged can't get inexistant call"; + } + return; + } auto& conversation = *i; auto uid = conversation.uid; @@ -1668,7 +1686,7 @@ void ConversationModelPimpl::slotCallAddedToConference(const std::string& callId, const std::string& confId) { for (auto& conversation: conversations) { - if (conversation.callId == callId) { + if (conversation.callId == callId || conversation.confId == confId) { conversation.confId = confId; dirtyConversations = {true, true}; emit linked.selectConversation(conversation.uid); diff --git a/src/lrc.cpp b/src/lrc.cpp index 91acd433..cbb795ec 100644 --- a/src/lrc.cpp +++ b/src/lrc.cpp @@ -149,6 +149,42 @@ Lrc::activeCalls() return result; } +std::vector<std::string> +Lrc::getCalls() +{ + QStringList callLists = CallManager::instance().getCallList(); + std::vector<std::string> result; + result.reserve(callLists.size()); + for (const auto &call : callLists) { + result.emplace_back(call.toStdString()); + } + return result; +} + +std::vector<std::string> +Lrc::getConferences() +{ + QStringList conferencesList = CallManager::instance().getConferenceList(); + std::vector<std::string> result; + result.reserve(conferencesList.size()); + for (const auto &conf : conferencesList) { + result.emplace_back(conf.toStdString()); + } + return result; +} + +std::vector<std::string> +Lrc::getConferenceSubcalls(const std::string& cid) +{ + QStringList callList = CallManager::instance().getParticipantList(cid.c_str()); + std::vector<std::string> result; + result.reserve(callList.size()); + foreach(const auto& callId, callList) { + result.emplace_back(callId.toStdString()); + } + return result; +} + bool isFinished(const QString& callState) { diff --git a/src/newcallmodel.cpp b/src/newcallmodel.cpp index b75425ae..1d3b5712 100644 --- a/src/newcallmodel.cpp +++ b/src/newcallmodel.cpp @@ -207,9 +207,12 @@ NewCallModel::getConferenceFromURI(const std::string& uri) const if (call.second->type == call::Type::CONFERENCE) { QStringList callList = CallManager::instance().getParticipantList(call.first.c_str()); foreach(const auto& callId, callList) { - if (pimpl_->calls[callId.toStdString()]->peerUri == uri) { - return *call.second; - } + try { + if (pimpl_->calls.find(callId.toStdString()) != pimpl_->calls.end() + && pimpl_->calls[callId.toStdString()]->peerUri == uri) { + return *call.second; + } + } catch (...) {} } } } @@ -372,18 +375,70 @@ NewCallModel::transferToCall(const std::string& callId, const std::string& callI void NewCallModel::joinCalls(const std::string& callIdA, const std::string& callIdB) const { - if (!hasCall(callIdA) || !hasCall(callIdB)) return; - - auto& call1 = pimpl_->calls[callIdA]; - auto& call2 = pimpl_->calls[callIdB]; - if (call1->type == call::Type::CONFERENCE && call2->type == call::Type::CONFERENCE) - CallManager::instance().joinConference(callIdA.c_str(), callIdB.c_str()); - else if (call1->type == call::Type::CONFERENCE) - CallManager::instance().addParticipant(callIdB.c_str(), callIdA.c_str()); - else if (call2->type == call::Type::CONFERENCE) - CallManager::instance().addParticipant(callIdA.c_str(), callIdB.c_str()); - else + // Get call informations + call::Info call1, call2; + std::string accountIdCall1 = {}, accountIdCall2 = {}; + for (const auto &account_id : owner.accountModel->getAccountList()) { + try { + auto &accountInfo = owner.accountModel->getAccountInfo(account_id); + if (accountInfo.callModel->hasCall(callIdA)) { + call1 = accountInfo.callModel->getCall(callIdA); + accountIdCall1 = account_id; + } + if (accountInfo.callModel->hasCall(callIdB)) { + call2 = accountInfo.callModel->getCall(callIdB); + accountIdCall2 = account_id; + } + if (!accountIdCall1.empty() && !accountIdCall2.empty()) break; + } catch (...) {} + } + if (accountIdCall1.empty() || accountIdCall2.empty()) { + qWarning() << "Can't join inexistent calls."; + return; + } + + if (call1.type == call::Type::CONFERENCE && call2.type == call::Type::CONFERENCE) { + bool joined = CallManager::instance().joinConference(callIdA.c_str(), callIdB.c_str()); + + if (!joined) { + qWarning() << "Conference: " << callIdA.c_str() << " couldn't join conference " << callIdB.c_str(); + return; + } + if (accountIdCall1 != owner.id) { + // If the conference is added from another account + try { + auto &accountInfo = owner.accountModel->getAccountInfo(accountIdCall1); + if (accountInfo.callModel->hasCall(callIdA)) { + emit accountInfo.callModel->callAddedToConference(callIdA, callIdB); + } + } catch (...) {} + } else { + emit callAddedToConference(callIdA, callIdB); + } + } else if (call1.type == call::Type::CONFERENCE || call2.type == call::Type::CONFERENCE) { + auto call = call1.type == call::Type::CONFERENCE ? callIdB : callIdA; + auto conf = call1.type == call::Type::CONFERENCE ? callIdA : callIdB; + auto accountCall = call1.type == call::Type::CONFERENCE ? accountIdCall2 : accountIdCall1; + bool joined = CallManager::instance().addParticipant(call.c_str(), conf.c_str()); + if (!joined) { + qWarning() << "Call: " << call.c_str() << " couldn't join conference " << conf.c_str(); + return; + } + if (accountCall != owner.id) { + // If the call is added from another account + try { + auto &accountInfo = owner.accountModel->getAccountInfo(accountCall); + if (accountInfo.callModel->hasCall(call)) { + accountInfo.callModel->pimpl_->slotConferenceCreated(conf); + } + } catch (...) {} + } else + emit callAddedToConference(call, conf); + } + else { CallManager::instance().joinParticipant(callIdA.c_str(), callIdB.c_str()); + // NOTE: This will trigger slotConferenceCreated. + } } void -- GitLab