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();