From 56fdc19e9521bca1387acbe8ac92eabad17d2d31 Mon Sep 17 00:00:00 2001
From: Roxie Linden <roxie@lindenlab.com>
Date: Sat, 3 Feb 2024 18:29:17 -0800
Subject: Checkpoint mute/volume

---
 indra/newview/llvoicewebrtc.cpp | 115 ++++++++++++++++++++++++++++++++++++----
 indra/newview/llvoicewebrtc.h   |  20 ++++++-
 2 files changed, 124 insertions(+), 11 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/llvoicewebrtc.cpp b/indra/newview/llvoicewebrtc.cpp
index 17b61465cc..e59e267d31 100644
--- a/indra/newview/llvoicewebrtc.cpp
+++ b/indra/newview/llvoicewebrtc.cpp
@@ -291,10 +291,6 @@ LLWebRTCVoiceClient::LLWebRTCVoiceClient() :
 	mVoiceVersion.serverVersion = "";
 	mVoiceVersion.serverType = VOICE_SERVER_TYPE;
 	
-	//  gMuteListp isn't set up at this point, so we defer this until later.
-//	gMuteListp->addObserver(&mutelist_listener);
-
-	
 #if LL_DARWIN || LL_LINUX
 		// HACK: THIS DOES NOT BELONG HERE
 		// When the WebRTC daemon dies, the next write attempt on our socket generates a SIGPIPE, which kills us.
@@ -550,6 +546,7 @@ void LLWebRTCVoiceClient::voiceConnectionCoro()
     LLCoros::set_consuming(true);
     try
     {
+        LLMuteList::getInstance()->addObserver(this);
         while (!sShuttingDown)
         {
             llcoro::suspendUntilTimeout(UPDATE_THROTTLE_SECONDS);
@@ -919,6 +916,26 @@ void LLWebRTCVoiceClient::sessionState::setSpeakerVolume(F32 volume)
     }
 }
 
+void LLWebRTCVoiceClient::sessionState::setUserVolume(const LLUUID& id, F32 volume)
+{
+    for (auto& connection : mWebRTCConnections)
+    {
+        connection->setUserVolume(id, volume);
+    }
+}
+
+void LLWebRTCVoiceClient::sessionState::setUserMute(const LLUUID& id, bool mute)
+{
+    if (mParticipantsByUUID.find(id) != mParticipantsByUUID.end())
+    {
+        return;
+    }
+    for (auto& connection : mWebRTCConnections)
+    {
+        connection->setUserMute(id, mute);
+    }
+}
+
 void LLWebRTCVoiceClient::sendLocalAudioUpdates()
 {
 }
@@ -1650,6 +1667,20 @@ void LLWebRTCVoiceClient::predSetMicGain(const LLWebRTCVoiceClient::sessionState
     session->setMicGain(gain);
 }
 
+void LLWebRTCVoiceClient::predSetUserMute(const LLWebRTCVoiceClient::sessionStatePtr_t &session,
+                                          const LLUUID &id,
+                                          bool mute)
+{
+    session->setUserMute(id, mute);
+}
+
+void LLWebRTCVoiceClient::predSetUserVolume(const LLWebRTCVoiceClient::sessionStatePtr_t &session,
+                                          const LLUUID &id,
+                                          F32 volume)
+{
+    session->setUserVolume(id, volume);
+}
+
 void LLWebRTCVoiceClient::setVoiceEnabled(bool enabled)
 {
     LL_DEBUGS("Voice")
@@ -1793,8 +1824,6 @@ std::string LLWebRTCVoiceClient::getDisplayName(const LLUUID& id)
 	return result;
 }
 
-
-
 BOOL LLWebRTCVoiceClient::getIsSpeaking(const LLUUID& id)
 {
 	BOOL result = FALSE;
@@ -1893,6 +1922,7 @@ F32 LLWebRTCVoiceClient::getUserVolume(const LLUUID& id)
 
 void LLWebRTCVoiceClient::setUserVolume(const LLUUID& id, F32 volume)
 {
+    F32 clamped_volume = llclamp(volume, LLVoiceClient::VOLUME_MIN, LLVoiceClient::VOLUME_MAX);
 	if(mSession)
 	{
         participantStatePtr_t participant(mSession->findParticipant(id.asString()));
@@ -1910,11 +1940,12 @@ void LLWebRTCVoiceClient::setUserVolume(const LLUUID& id, F32 volume)
 				LLSpeakerVolumeStorage::getInstance()->removeSpeakerVolume(id);
 			}
 
-			participant->mVolume = llclamp(volume, LLVoiceClient::VOLUME_MIN, LLVoiceClient::VOLUME_MAX);
+			participant->mVolume = clamped_volume;
 			participant->mVolumeDirty = true;
 			mSession->mVolumeDirty = true;
 		}
 	}
+    sessionState::for_each(boost::bind(predSetUserVolume, _1, id, clamped_volume));
 }
 
 std::string LLWebRTCVoiceClient::getGroupID(const LLUUID& id)
@@ -1930,6 +1961,24 @@ std::string LLWebRTCVoiceClient::getGroupID(const LLUUID& id)
 	return result;
 }
 
+////////////////////////
+///LLMuteListObserver
+///
+
+void LLWebRTCVoiceClient::onChange()
+{
+}
+
+void LLWebRTCVoiceClient::onChangeDetailed(const LLMute& mute)
+{
+    if (mute.mType == LLMute::AGENT)
+    {
+        bool muted = ((mute.mFlags & LLMute::flagVoiceChat) == 0);
+        sessionState::for_each(boost::bind(predSetUserMute, _1, mute.mID, muted));
+    }
+}
+
+
 BOOL LLWebRTCVoiceClient::getAreaVoiceDisabled()
 {
 	return mAreaVoiceDisabled;
@@ -2011,7 +2060,6 @@ void LLWebRTCVoiceClient::sessionState::reapEmptySessions()
     }
 }
 
-
 bool LLWebRTCVoiceClient::sessionState::testByCreatingURI(const LLWebRTCVoiceClient::sessionState::wptr_t &a, std::string uri)
 {
     ptr_t aLock(a.lock());
@@ -2153,7 +2201,6 @@ void LLWebRTCVoiceClient::notifyStatusObservers(LLVoiceClientStatusObserver::ESt
     LL_DEBUGS("Voice") << "( " << LLVoiceClientStatusObserver::status2string(status) << " )"
                        << " mSession=" << mSession
                        << LL_ENDL;
-
 	if(mSession)
 	{
 		if(status == LLVoiceClientStatusObserver::ERROR_UNKNOWN)
@@ -2531,6 +2578,29 @@ void LLVoiceWebRTCConnection::setSpeakerVolume(F32 volume)
     }
 }
 
+void LLVoiceWebRTCConnection::setUserVolume(const LLUUID& id, F32 volume)
+{
+    Json::Value root = Json::objectValue;
+    Json::Value user_gain = Json::objectValue;
+    user_gain[id.asString()] = (uint32_t)volume*100;
+    root["ug"] = user_gain;
+    Json::FastWriter writer;
+    std::string json_data = writer.write(root);
+    mWebRTCDataInterface->sendData(json_data, false);
+}
+
+void LLVoiceWebRTCConnection::setUserMute(const LLUUID& id, bool mute)
+{
+    Json::Value root = Json::objectValue;
+    Json::Value muted = Json::objectValue;
+    muted[id.asString()] = mute;
+    root["m"] = muted;
+    Json::FastWriter writer;
+    std::string json_data = writer.write(root);
+    mWebRTCDataInterface->sendData(json_data, false);
+}
+
+
 void LLVoiceWebRTCConnection::sendData(const std::string &data)
 {
     if (getVoiceConnectionState() == VOICE_STATE_SESSION_UP && mWebRTCDataInterface)
@@ -2825,6 +2895,8 @@ void LLVoiceWebRTCConnection::OnDataReceived(const std::string &data, bool binar
             return;
         }
         bool new_participant = false;
+        Json::Value      mute = Json::objectValue;
+        Json::Value      user_gain = Json::objectValue;
         for (auto &participant_id : voice_data.getMemberNames())
         {
             LLUUID agent_id(participant_id);
@@ -2842,6 +2914,16 @@ void LLVoiceWebRTCConnection::OnDataReceived(const std::string &data, bool binar
             {
                 joined  = true;
                 primary = voice_data[participant_id]["j"].get("p", Json::Value(false)).asBool();
+                bool isMuted = LLMuteList::getInstance()->isMuted(agent_id, LLMute::flagVoiceChat);
+                if (isMuted)
+                {
+                    mute[participant_id] = true;
+                }
+                F32 volume;
+                if(LLSpeakerVolumeStorage::getInstance()->getSpeakerVolume(agent_id, volume))
+                {
+                    user_gain[participant_id] = volume;
+                }
             }
 
             new_participant |= joined;
@@ -2869,6 +2951,21 @@ void LLVoiceWebRTCConnection::OnDataReceived(const std::string &data, bool binar
                 }
             }
         }
+        Json::FastWriter writer;
+        Json::Value      root     = Json::objectValue;
+        if (mute.size() > 0)
+        {
+            root["m"] = mute;
+        }
+        if (user_gain.size() > 0)
+        {
+            root["ug"] = user_gain;
+        }
+        if (root.size() > 0)
+        {
+            std::string json_data = writer.write(root);
+            mWebRTCDataInterface->sendData(json_data, false);
+        }
     }
 }
 
diff --git a/indra/newview/llvoicewebrtc.h b/indra/newview/llvoicewebrtc.h
index e1a740929b..d7d6ca6229 100644
--- a/indra/newview/llvoicewebrtc.h
+++ b/indra/newview/llvoicewebrtc.h
@@ -40,6 +40,7 @@ class LLWebRTCProtocolParser;
 #include "lleventcoro.h"
 #include "llcoros.h"
 #include "llparcel.h"
+#include "llmutelist.h"
 #include <queue>
 #include "json/reader.h"
 
@@ -60,7 +61,8 @@ typedef boost::shared_ptr<LLVoiceWebRTCConnection> connectionPtr_t;
 class LLWebRTCVoiceClient :	public LLSingleton<LLWebRTCVoiceClient>,
 							virtual public LLVoiceModuleInterface,
 							virtual public LLVoiceEffectInterface,
-                            public llwebrtc::LLWebRTCDevicesObserver
+                            public llwebrtc::LLWebRTCDevicesObserver,
+                            public LLMuteListObserver
 {
     LLSINGLETON_C11(LLWebRTCVoiceClient);
 	LOG_CLASS(LLWebRTCVoiceClient);
@@ -240,6 +242,13 @@ public:
 
     bool isPreviewRecording() override { return false;  }
     bool isPreviewPlaying() override { return false; }
+    //@}
+    
+    //////////////////
+    /// @name LLMuteListObserver
+    //@{
+    void onChange() override;
+    void onChangeDetailed(const LLMute& ) override;
     //@}
 
 	// authorize the user
@@ -344,6 +353,9 @@ public:
         void setMuteMic(bool muted);
         void setMicGain(F32 volume);
         void setSpeakerVolume(F32 volume);
+        void setUserVolume(const LLUUID& id, F32 volume);
+        
+        void setUserMute(const LLUUID& id, bool mute);
 		
         static void for_each(sessionFunc_t func);
 
@@ -454,6 +466,8 @@ public:
     static void predSetMicGain(const LLWebRTCVoiceClient::sessionStatePtr_t &session, F32 volume);
     static void predSetSpeakerVolume(const LLWebRTCVoiceClient::sessionStatePtr_t &session, F32 volume);
     static void predShutdownSession(const LLWebRTCVoiceClient::sessionStatePtr_t &session);
+    static void predSetUserMute(const LLWebRTCVoiceClient::sessionStatePtr_t &session, const LLUUID& id, bool mute);
+    static void predSetUserVolume(const LLWebRTCVoiceClient::sessionStatePtr_t &session, const LLUUID& id, F32 volume);
 
 	//////////////////////////////
 	/// @name TVC/Server management and communication
@@ -765,7 +779,9 @@ class LLVoiceWebRTCConnection :
     virtual void setMuteMic(bool muted);
     virtual void setMicGain(F32 volume);
     virtual void setSpeakerVolume(F32 volume);
-
+    
+    void setUserVolume(const LLUUID& id, F32 volume);
+    void setUserMute(const LLUUID& id, bool mute);
 
     bool connectionStateMachine();
 
-- 
cgit v1.2.3