diff --git a/bin/dbus/cx.ring.Ring.CallManager.xml b/bin/dbus/cx.ring.Ring.CallManager.xml index 7ae32d13d..febb490e8 100644 --- a/bin/dbus/cx.ring.Ring.CallManager.xml +++ b/bin/dbus/cx.ring.Ring.CallManager.xml @@ -251,6 +251,12 @@ + + + + + + diff --git a/bin/dbus/dbuscallmanager.cpp b/bin/dbus/dbuscallmanager.cpp index ff4da4884..9ccbc7146 100644 --- a/bin/dbus/dbuscallmanager.cpp +++ b/bin/dbus/dbuscallmanager.cpp @@ -297,3 +297,9 @@ DBusCallManager::stopSmartInfo() { DRing::stopSmartInfo(); } + +void +DBusCallManager::setModerator(const std::string& confId, const std::string& peerId, const bool& state) +{ + DRing::setModerator(confId, peerId, state); +} diff --git a/bin/dbus/dbuscallmanager.h b/bin/dbus/dbuscallmanager.h index bb3f547c1..ecbe7f64e 100644 --- a/bin/dbus/dbuscallmanager.h +++ b/bin/dbus/dbuscallmanager.h @@ -101,6 +101,7 @@ class DRING_PUBLIC DBusCallManager : void sendTextMessage(const std::string& callID, const std::map& messages, const bool& isMixed); void startSmartInfo(const uint32_t& refreshTimeMs); void stopSmartInfo(); + void setModerator(const std::string& confId, const std::string& peerId, const bool& state); }; #endif // __RING_CALLMANAGER_H__ diff --git a/bin/jni/callmanager.i b/bin/jni/callmanager.i index 077e6b4b8..d0167c43c 100644 --- a/bin/jni/callmanager.i +++ b/bin/jni/callmanager.i @@ -92,6 +92,7 @@ std::vector getDisplayNames(const std::string& confID); std::string getConferenceId(const std::string& callID); std::map getConferenceDetails(const std::string& callID); std::vector> getConferenceInfos(const std::string& confId); +void setModerator(const std::string& confId, const std::string& peerId, const bool& state); /* File Playback methods */ bool startRecordedFilePlayback(const std::string& filepath); diff --git a/bin/nodejs/callmanager.i b/bin/nodejs/callmanager.i index b213005a0..4b5fdc40f 100644 --- a/bin/nodejs/callmanager.i +++ b/bin/nodejs/callmanager.i @@ -90,6 +90,7 @@ std::vector getDisplayNames(const std::string& confID); std::string getConferenceId(const std::string& callID); std::map getConferenceDetails(const std::string& callID); std::vector> getConferenceInfos(const std::string& confId); +void setModerator(const std::string& confId, const std::string& peerId, const bool& state); /* File Playback methods */ bool startRecordedFilePlayback(const std::string& filepath); diff --git a/configure.ac b/configure.ac index 604c07c7c..c59ca2726 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ dnl Jami - configure.ac for automake 1.9 and autoconf 2.59 dnl Process this file with autoconf to produce a configure script. AC_PREREQ([2.65]) -AC_INIT([Jami Daemon],[9.5.0],[ring@gnu.org],[jami]) +AC_INIT([Jami Daemon],[9.6.0],[ring@gnu.org],[jami]) AC_COPYRIGHT([[Copyright (c) Savoir-faire Linux 2004-2020]]) AC_REVISION([$Revision$]) diff --git a/src/client/callmanager.cpp b/src/client/callmanager.cpp index 12616ef28..bd7b63bc7 100644 --- a/src/client/callmanager.cpp +++ b/src/client/callmanager.cpp @@ -343,4 +343,12 @@ sendTextMessage(const std::string& callID, }); } +void +setModerator(const std::string& confId, + const std::string& peerId, + const bool& state) +{ + jami::Manager::instance().setModerator(confId, peerId, state); +} + } // namespace DRing diff --git a/src/conference.cpp b/src/conference.cpp index 4aa222e35..88550b8ee 100644 --- a/src/conference.cpp +++ b/src/conference.cpp @@ -53,11 +53,10 @@ Conference::Conference() // conference master. In the future, this should be // retrieven with another way auto accounts = jami::Manager::instance().getAllAccounts(); - moderators_.reserve(accounts.size()); for (const auto& account : accounts) { if (!account) continue; - moderators_.emplace_back(account->getUsername()); + moderators_.emplace(account->getUsername()); } #ifdef ENABLE_VIDEO @@ -493,7 +492,7 @@ Conference::onConfOrder(const std::string& callId, const std::string& confOrder) auto uri = call->getPeerNumber(); auto separator = uri.find('@'); if (separator != std::string::npos) - uri = uri.substr(0, separator - 1); + uri = uri.substr(0, separator); if (!isModerator(uri)) { JAMI_WARN("Received conference order from a non master (%s)", uri.c_str()); return; @@ -527,4 +526,46 @@ Conference::isModerator(const std::string& uri) const != moderators_.end(); } +void +Conference::setModerator(const std::string& uri, const bool& state) +{ + for (const auto& p : participants_) { + if (auto call = Manager::instance().callFactory.getCall(p)) { + auto partURI = call->getPeerNumber(); + auto separator = partURI.find('@'); + if (separator != std::string::npos) + partURI = partURI.substr(0, separator); + if (partURI == uri) { + if (state and not isModerator(uri)) { + JAMI_DBG("Add %s as moderator", partURI.c_str()); + moderators_.emplace(uri); + updateModerators(); + } else if (not state and isModerator(uri)) { + JAMI_DBG("Remove %s as moderator", partURI.c_str()); + moderators_.erase(uri); + updateModerators(); + } + return; + } + } + } + JAMI_WARN("Fail to set %s as moderator (participant not found)", uri.c_str()); +} + +void +Conference::updateModerators() +{ + { + std::lock_guard lk2(confInfoMutex_); + for (auto& info : confInfo_) { + auto uri = info.uri; + auto separator = uri.find('@'); + if (separator != std::string::npos) + uri = uri.substr(0, separator); + info.isModerator = isModerator(uri); + } + } + sendConferenceInfos(); +} + } // namespace jami diff --git a/src/conference.h b/src/conference.h index 709274b23..51c338aee 100644 --- a/src/conference.h +++ b/src/conference.h @@ -202,6 +202,7 @@ public: void detachVideo(Observable>* frame); void onConfOrder(const std::string& callId, const std::string& order); + void setModerator(const std::string& uri, const bool& state); #ifdef ENABLE_VIDEO std::shared_ptr getVideoMixer(); @@ -240,10 +241,12 @@ private: #endif std::shared_ptr audioMixer_; - std::vector moderators_ {}; + std::set moderators_ {}; void initRecorder(std::shared_ptr& rec); void deinitRecorder(std::shared_ptr& rec); + + void updateModerators(); }; } // namespace jami diff --git a/src/dring/callmanager_interface.h b/src/dring/callmanager_interface.h index 41baed45c..0fb9873aa 100644 --- a/src/dring/callmanager_interface.h +++ b/src/dring/callmanager_interface.h @@ -77,6 +77,7 @@ DRING_PUBLIC std::string getConferenceId(const std::string& callID); DRING_PUBLIC std::map getConferenceDetails(const std::string& callID); DRING_PUBLIC std::vector> getConferenceInfos( const std::string& confId); +DRING_PUBLIC void setModerator(const std::string& confId, const std::string& peerId, const bool& state); /* Statistic related methods */ DRING_PUBLIC void startSmartInfo(uint32_t refreshTimeMs); diff --git a/src/manager.cpp b/src/manager.cpp index 413cd3703..b92a8b592 100644 --- a/src/manager.cpp +++ b/src/manager.cpp @@ -3222,4 +3222,13 @@ Manager::getNearbyPeers(const std::string& accountID) return {}; } +void +Manager::setModerator(const std::string& confId, const std::string& peerId, const bool& state) +{ + if (auto conf = getConferenceFromID(confId)) { + conf->setModerator(peerId, state); + } else + JAMI_WARN("Fail to change moderator %s, conference %s not found", peerId.c_str(), confId.c_str()); +} + } // namespace jami diff --git a/src/manager.h b/src/manager.h index db7420e28..759f78fc2 100644 --- a/src/manager.h +++ b/src/manager.h @@ -934,6 +934,8 @@ public: JamiPluginManager& getJamiPluginManager() const; #endif + void setModerator(const std::string& confId, const std::string& peerId, const bool& state); + private: Manager(); ~Manager();