diff --git a/src/app/lrcinstance.cpp b/src/app/lrcinstance.cpp index a44f03f2..21b2254c 100644 --- a/src/app/lrcinstance.cpp +++ b/src/app/lrcinstance.cpp @@ -111,9 +111,9 @@ LRCInstance::isConnected() } VectorString -LRCInstance::getActiveCalls() +LRCInstance::getActiveCalls(const QString& accountId) { - return lrc_->activeCalls(); + return lrc_->activeCalls(accountId); } int diff --git a/src/app/lrcinstance.h b/src/app/lrcinstance.h index d4a88928..d8e7a495 100644 --- a/src/app/lrcinstance.h +++ b/src/app/lrcinstance.h @@ -83,7 +83,7 @@ public: void subscribeToDebugReceived(); bool isConnected(); void connectivityChanged(); - VectorString getActiveCalls(); + VectorString getActiveCalls(const QString& accountId = ""); int notificationsCount() const; const account::Info& getAccountInfo(const QString& accountId); diff --git a/src/app/utilsadapter.cpp b/src/app/utilsadapter.cpp index d27c0f70..ac205fb1 100644 --- a/src/app/utilsadapter.cpp +++ b/src/app/utilsadapter.cpp @@ -194,7 +194,7 @@ UtilsAdapter::getAccountListSize() bool UtilsAdapter::hasCall(const QString& accountId) { - auto activeCalls = lrcInstance_->getActiveCalls(); + auto activeCalls = lrcInstance_->getActiveCalls(accountId); for (const auto& callId : activeCalls) { auto& accountInfo = lrcInstance_->accountModel().getAccountInfo(accountId); if (accountInfo.callModel->hasCall(callId)) { @@ -208,7 +208,7 @@ const QString UtilsAdapter::getCallConvForAccount(const QString& accountId) { // TODO: Currently returning first call, establish priority according to state? - for (const auto& callId : lrcInstance_->getActiveCalls()) { + for (const auto& callId : lrcInstance_->getActiveCalls(accountId)) { auto& accountInfo = lrcInstance_->accountModel().getAccountInfo(accountId); if (accountInfo.callModel->hasCall(callId)) { return lrcInstance_->getConversationFromCallId(callId, accountId).uid; diff --git a/src/libclient/api/lrc.h b/src/libclient/api/lrc.h index 1c4199b0..9d8c9e81 100644 --- a/src/libclient/api/lrc.h +++ b/src/libclient/api/lrc.h @@ -92,7 +92,7 @@ public: /** * Helper: get active call list from daemon */ - static VectorString activeCalls(); + static VectorString activeCalls(const QString& accountId = ""); /** * Close all active calls and conferences diff --git a/src/libclient/callmodel.cpp b/src/libclient/callmodel.cpp index baf1a19a..ea1f5d6a 100644 --- a/src/libclient/callmodel.cpp +++ b/src/libclient/callmodel.cpp @@ -1060,36 +1060,44 @@ CallModel::setCurrentCall(const QString& callId) const } } - VectorString filterCalls; - QStringList conferences = CallManager::instance().getConferenceList(owner.id); - for (const auto& confId : conferences) { - QStringList callList = CallManager::instance().getParticipantList(owner.id, confId); - Q_FOREACH (const auto& cid, callList) { - filterCalls.push_back(cid); + QStringList accountList = pimpl_->lrc.getAccountModel().getAccountList(); + // If we are setting a current call in the UI, we want to hold all other calls, + // across accounts, to avoid sending our local media streams while another call + // is in focus. + for (const auto& acc : accountList) { + VectorString filterCalls; + // For each account, we should not hold calls linked to a conference + QStringList conferences = CallManager::instance().getConferenceList(acc); + for (const auto& confId : conferences) { + QStringList callList = CallManager::instance().getParticipantList(acc, confId); + Q_FOREACH (const auto& cid, callList) { + filterCalls.push_back(cid); + } } - } - for (const auto& cid : Lrc::activeCalls()) { - auto filtered = std::find(filterCalls.begin(), filterCalls.end(), cid) != filterCalls.end(); - if (cid != callId && !filtered) { - // Only hold calls for a non rendez-vous point - MapStringString callDetails = CallManager::instance().getCallDetails(owner.id, callId); - auto accountId = callDetails["ACCOUNTID"]; - CallManager::instance().hold(owner.id, cid); + + for (const auto& cid : Lrc::activeCalls(acc)) { + auto filtered = std::find(filterCalls.begin(), filterCalls.end(), cid) != filterCalls.end(); + if (cid != callId && !filtered) { + // Only hold calls for a non rendez-vous point + CallManager::instance().hold(acc, cid); + } } - } - if (!lrc::api::Lrc::holdConferences) { - return; - } - for (const auto& confId : conferences) { - if (callId != confId) { - MapStringString confDetails = CallManager::instance().getConferenceDetails(owner.id, - confId); - // Only hold conference if attached - if (confDetails["CALL_STATE"] == "ACTIVE_DETACHED") - continue; - QStringList callList = CallManager::instance().getParticipantList(owner.id, confId); - if (callList.indexOf(callId) == -1) - CallManager::instance().holdConference(owner.id, confId); + + if (!lrc::api::Lrc::holdConferences) { + return; + } + // If the account is the host and it is attached to the conference, + // then we should hold it. + for (const auto& confId : conferences) { + if (callId != confId) { + MapStringString confDetails = CallManager::instance().getConferenceDetails(acc, confId); + // Only hold conference if attached + if (confDetails["CALL_STATE"] == "ACTIVE_DETACHED") + continue; + QStringList callList = CallManager::instance().getParticipantList(acc, confId); + if (callList.indexOf(callId) == -1) + CallManager::instance().holdConference(acc, confId); + } } } } @@ -1372,6 +1380,7 @@ CallModelPimpl::slotCallStateChanged(const QString& accountId, || previousStatus == call::Status::OUTGOING_RINGING) { if (previousStatus == call::Status::INCOMING_RINGING && linked.owner.profileInfo.type != profile::Type::SIP + && !linked.owner.confProperties.autoAnswer && !linked.owner.confProperties.isRendezVous) { // TODO remove this when we want to // not show calls in rendez-vous linked.setCurrentCall(callId); diff --git a/src/libclient/lrc.cpp b/src/libclient/lrc.cpp index c8777ab9..fa031d49 100644 --- a/src/libclient/lrc.cpp +++ b/src/libclient/lrc.cpp @@ -148,11 +148,13 @@ Lrc::subscribeToDebugReceived() } VectorString -Lrc::activeCalls() +Lrc::activeCalls(const QString& accountId) { VectorString result; const QStringList accountIds = ConfigurationManager::instance().getAccountList(); for (const auto& accId : accountIds) { + if (!accountId.isEmpty() && accountId != accId) + continue; QStringList callLists = CallManager::instance().getCallList(accId); for (const auto& call : callLists) { MapStringString callDetails = CallManager::instance().getCallDetails(accId, call);