From cf2268635ca6aef99b1d6c01083be4b4a292646a Mon Sep 17 00:00:00 2001
From: Mike Antipov <mantipov@productengine.com>
Date: Thu, 27 May 2010 17:36:34 +0300
Subject: [PATCH] EXT-6937 FIXED Implemented initializing of moderate_mode on
 first join voice chat.

This is a workaround until a way to request the current voice channel moderation mode is implemented in the viewer.

Details:
* Added method to initialize Speaker manager's Voice moderate_mode once Agent's participant state is known.
* Once agent's voice participant is updated this method is called.
* This method initializes Voice moderate_mode  only once.

This is necessary to process "Mute everyone" menu item calls properly.

Also renamed moderateVoiceOtherParticipants methods with moderateVoiceAllParticipants and related staff.

Reviewed by Aimee Walton at https://codereview.productengine.com/secondlife/r/448/

--HG--
branch : product-engine
---
 indra/newview/llparticipantlist.cpp | 10 ++---
 indra/newview/llparticipantlist.h   | 10 ++---
 indra/newview/llspeakers.cpp        | 65 ++++++++++++++---------------
 indra/newview/llspeakers.h          | 30 ++++++++-----
 indra/newview/llvoicevivox.cpp      |  8 +++-
 5 files changed, 67 insertions(+), 56 deletions(-)

diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp
index b975536f8bc..4f0946774a4 100644
--- a/indra/newview/llparticipantlist.cpp
+++ b/indra/newview/llparticipantlist.cpp
@@ -793,7 +793,7 @@ void LLParticipantList::LLParticipantListMenu::moderateVoice(const LLSD& userdat
 	else
 	{
 		bool unmute_all = userdata.asString() == "unmute_all";
-		moderateVoiceOtherParticipants(LLUUID::null, unmute_all);
+		moderateVoiceAllParticipants(unmute_all);
 	}
 }
 
@@ -806,7 +806,7 @@ void LLParticipantList::LLParticipantListMenu::moderateVoiceParticipant(const LL
 	}
 }
 
-void LLParticipantList::LLParticipantListMenu::moderateVoiceOtherParticipants(const LLUUID& excluded_avatar_id, bool unmute)
+void LLParticipantList::LLParticipantListMenu::moderateVoiceAllParticipants(bool unmute)
 {
 	LLIMSpeakerMgr* mgr = dynamic_cast<LLIMSpeakerMgr*>(mParent.mSpeakerMgr);
 	if (mgr)
@@ -815,12 +815,11 @@ void LLParticipantList::LLParticipantListMenu::moderateVoiceOtherParticipants(co
 		{
 			LLSD payload;
 			payload["session_id"] = mgr->getSessionID();
-			payload["excluded_avatar_id"] = excluded_avatar_id;
 			LLNotificationsUtil::add("ConfirmMuteAll", LLSD(), payload, confirmMuteAllCallback);
 			return;
 		}
 
-		mgr->moderateVoiceOtherParticipants(excluded_avatar_id, unmute);
+		mgr->moderateVoiceAllParticipants(unmute);
 	}
 }
 
@@ -835,13 +834,12 @@ void LLParticipantList::LLParticipantListMenu::confirmMuteAllCallback(const LLSD
 
 	const LLSD& payload = notification["payload"];
 	const LLUUID& session_id = payload["session_id"];
-	const LLUUID& excluded_avatar_id = payload["excluded_avatar_id"];
 
 	LLIMSpeakerMgr * speaker_manager = dynamic_cast<LLIMSpeakerMgr*> (
 			LLIMModel::getInstance()->getSpeakerManager(session_id));
 	if (speaker_manager)
 	{
-		speaker_manager->moderateVoiceOtherParticipants(excluded_avatar_id, false);
+		speaker_manager->moderateVoiceAllParticipants(false);
 	}
 
 	return;
diff --git a/indra/newview/llparticipantlist.h b/indra/newview/llparticipantlist.h
index 967c8b78cf5..3fe45fa5919 100644
--- a/indra/newview/llparticipantlist.h
+++ b/indra/newview/llparticipantlist.h
@@ -187,7 +187,7 @@ class LLParticipantList
 			 * @param userdata can be "selected" or "others".
 			 *
 			 * @see moderateVoiceParticipant()
-			 * @see moderateVoiceOtherParticipants()
+			 * @see moderateVoiceAllParticipants()
 			 */
 			void moderateVoice(const LLSD& userdata);
 
@@ -200,22 +200,20 @@ class LLParticipantList
 			 * @param[in] avatar_id UUID of avatar to be processed
 			 * @param[in] unmute if true - specified avatar will be muted, otherwise - unmuted.
 			 *
-			 * @see moderateVoiceOtherParticipants()
+			 * @see moderateVoiceAllParticipants()
 			 */
 			void moderateVoiceParticipant(const LLUUID& avatar_id, bool unmute);
 
 			/**
-			 * Mutes/Unmutes all avatars except specified for current group voice chat.
+			 * Mutes/Unmutes all avatars for current group voice chat.
 			 *
 			 * It only marks avatars as muted for session and does not use local Agent's Block list.
-			 * It based call moderateVoiceParticipant() for each avatar should be muted/unmuted.
 			 *
-			 * @param[in] excluded_avatar_id UUID of avatar NOT to be processed
 			 * @param[in] unmute if true - avatars will be muted, otherwise - unmuted.
 			 *
 			 * @see moderateVoiceParticipant()
 			 */
-			void moderateVoiceOtherParticipants(const LLUUID& excluded_avatar_id, bool unmute);
+			void moderateVoiceAllParticipants(bool unmute);
 
 			static void confirmMuteAllCallback(const LLSD& notification, const LLSD& response);
 		};
diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp
index 9da3db30328..bf00b47c214 100644
--- a/indra/newview/llspeakers.cpp
+++ b/indra/newview/llspeakers.cpp
@@ -251,6 +251,8 @@ bool LLSpeakersDelayActionsStorage::onTimerActionCallback(const LLUUID& speaker_
 
 LLSpeakerMgr::LLSpeakerMgr(LLVoiceChannel* channelp) : 
 	mVoiceChannel(channelp)
+, mVoiceModerated(false)
+, mModerateModeHandledFirstTime(false)
 {
 	static LLUICachedControl<F32> remove_delay ("SpeakerParticipantRemoveDelay", 10.0);
 
@@ -297,6 +299,33 @@ LLPointer<LLSpeaker> LLSpeakerMgr::setSpeaker(const LLUUID& id, const std::strin
 	return speakerp;
 }
 
+// *TODO: Once way to request the current voice channel moderation mode is implemented
+// this method with related code should be removed.
+/*
+ Initializes "moderate_mode" of voice session on first join.
+ 
+ This is WORKAROUND because a way to request the current voice channel moderation mode exists
+ but is not implemented in viewer yet. See EXT-6937.
+*/
+void LLSpeakerMgr::initVoiceModerateMode()
+{
+	if (!mModerateModeHandledFirstTime && (mVoiceChannel && mVoiceChannel->isActive()))
+	{
+		LLPointer<LLSpeaker> speakerp;
+
+		if (mSpeakers.find(gAgentID) != mSpeakers.end())
+		{
+			speakerp = mSpeakers[gAgentID];
+		}
+
+		if (speakerp.notNull())
+		{
+			mVoiceModerated = speakerp->mModeratorMutedVoice;
+			mModerateModeHandledFirstTime = true;
+		}
+	}
+}
+
 void LLSpeakerMgr::update(BOOL resort_ok)
 {
 	if (!LLVoiceClient::getInstance())
@@ -529,7 +558,6 @@ BOOL LLSpeakerMgr::isVoiceActive()
 // LLIMSpeakerMgr
 //
 LLIMSpeakerMgr::LLIMSpeakerMgr(LLVoiceChannel* channel) : LLSpeakerMgr(channel)
-, mVoiceModerated(false)
 {
 }
 
@@ -762,31 +790,9 @@ void LLIMSpeakerMgr::moderateVoiceParticipant(const LLUUID& avatar_id, bool unmu
 		new ModerationResponder(getSessionID()));
 }
 
-void LLIMSpeakerMgr::moderateVoiceOtherParticipants(const LLUUID& excluded_avatar_id, bool unmute_everyone_else)
+void LLIMSpeakerMgr::moderateVoiceAllParticipants( bool unmute_everyone )
 {
-	// *TODO: mantipov: add more intellectual processing of several following requests if it is needed.
-	/*
-		Such situation should be tested:
-		 "Moderator sends the same second request before first response is come"
-		Moderator sends "mute everyone else" for A and then for B
-			two requests to disallow voice chat are sent
-			UUID of B is stored.
-		Then first response (to disallow voice chat) is come
-			request to allow voice for stored avatar (B)
-		Then second response (to disallow voice chat) is come
-			have nothing to do, the latest selected speaker is already enabled
-
-			What can happen?
-		If request to allow voice for stored avatar (B) is processed on server BEFORE 
-		second request to disallow voice chat all speakers will be disabled on voice.
-		But I'm not sure such situation is possible. 
-		See EXT-3431.
-	*/
-
-	mReverseVoiceModeratedAvatarID = excluded_avatar_id;
-
-
-	if (mVoiceModerated == !unmute_everyone_else)
+	if (mVoiceModerated == !unmute_everyone)
 	{
 		// session already in requested state. Just force participants which do not match it.
 		forceVoiceModeratedMode(mVoiceModerated);
@@ -794,7 +800,7 @@ void LLIMSpeakerMgr::moderateVoiceOtherParticipants(const LLUUID& excluded_avata
 	else
 	{
 		// otherwise set moderated mode for a whole session.
-		moderateVoiceSession(getSessionID(), !unmute_everyone_else);
+		moderateVoiceSession(getSessionID(), !unmute_everyone);
 	}
 }
 
@@ -804,13 +810,6 @@ void LLIMSpeakerMgr::processSessionUpdate(const LLSD& session_update)
 		session_update["moderated_mode"].has("voice"))
 	{
 		mVoiceModerated = session_update["moderated_mode"]["voice"];
-
-		if (mReverseVoiceModeratedAvatarID.notNull())
-		{
-			moderateVoiceParticipant(mReverseVoiceModeratedAvatarID, mVoiceModerated);
-
-			mReverseVoiceModeratedAvatarID = LLUUID::null;
-		}
 	}
 }
 
diff --git a/indra/newview/llspeakers.h b/indra/newview/llspeakers.h
index b38acb7bc4d..4a250de82fc 100644
--- a/indra/newview/llspeakers.h
+++ b/indra/newview/llspeakers.h
@@ -242,6 +242,13 @@ class LLSpeakerMgr : public LLOldEvents::LLObservable
 	 */
 	bool removeAvalineSpeaker(const LLUUID& speaker_id) { return removeSpeaker(speaker_id); }
 
+	/**
+	 * Initializes mVoiceModerated depend on LLSpeaker::mModeratorMutedVoice of agent's participant.
+	 *
+	 * Is used only to implement workaround to initialize mVoiceModerated on first join to group chat. See EXT-6937
+	 */
+	void initVoiceModerateMode();
+
 protected:
 	virtual void updateSpeakerList();
 	void setSpeakerNotInChannel(LLSpeaker* speackerp);
@@ -258,6 +265,14 @@ class LLSpeakerMgr : public LLOldEvents::LLObservable
 	 * time out speakers when they are not part of current session
 	 */
 	LLSpeakersDelayActionsStorage* mSpeakerDelayRemover;
+
+	// *TODO: should be moved back into LLIMSpeakerMgr when a way to request the current voice channel
+	// moderation mode is implemented: See EXT-6937
+	bool mVoiceModerated;
+
+	// *TODO: To be removed when a way to request the current voice channel
+	// moderation mode is implemented: See EXT-6937
+	bool mModerateModeHandledFirstTime;
 };
 
 class LLIMSpeakerMgr : public LLSpeakerMgr
@@ -279,22 +294,21 @@ class LLIMSpeakerMgr : public LLSpeakerMgr
 	 * @param[in] avatar_id UUID of avatar to be processed
 	 * @param[in] unmute if false - specified avatar will be muted, otherwise - unmuted.
 	 *
-	 * @see moderateVoiceOtherParticipants()
+	 * @see moderateVoiceAllParticipants()
 	 */
 	void moderateVoiceParticipant(const LLUUID& avatar_id, bool unmute);
 
 	/**
-	 * Mutes/Unmutes all avatars except specified for current group voice chat.
+	 * Mutes/Unmutes all avatars for current group voice chat.
 	 *
 	 * It only marks avatars as muted for session and does not use local Agent's Block list.
-	 * It based call moderateVoiceParticipant() for each avatar should be muted/unmuted.
+	 * It calls forceVoiceModeratedMode() in case of session is already in requested state.
 	 *
-	 * @param[in] excluded_avatar_id UUID of avatar NOT to be processed
-	 * @param[in] unmute_everyone_else if false - avatars will be muted, otherwise - unmuted.
+	 * @param[in] unmute_everyone if false - avatars will be muted, otherwise - unmuted.
 	 *
 	 * @see moderateVoiceParticipant()
 	 */
-	void moderateVoiceOtherParticipants(const LLUUID& excluded_avatar_id, bool unmute_everyone_else);
+	void moderateVoiceAllParticipants(bool unmute_everyone);
 
 	void processSessionUpdate(const LLSD& session_update);
 
@@ -308,10 +322,6 @@ class LLIMSpeakerMgr : public LLSpeakerMgr
 	 */
 	void forceVoiceModeratedMode(bool should_be_muted);
 
-private:
-	LLUUID mReverseVoiceModeratedAvatarID;
-	bool mVoiceModerated;
-
 };
 
 class LLActiveSpeakerMgr : public LLSpeakerMgr, public LLSingleton<LLActiveSpeakerMgr>
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index bcb1a70efbe..15976913475 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -3698,9 +3698,15 @@ void LLVivoxVoiceClient::participantUpdatedEvent(
 				if (speaker_manager)
 				{
 					speaker_manager->update(true);
+
+					// also initialize voice moderate_mode depend on Agent's participant. See EXT-6937.
+					// *TODO: remove once a way to request the current voice channel moderation mode is implemented.
+					if (gAgentID == participant->mAvatarID)
+					{
+						speaker_manager->initVoiceModerateMode();
+					}
 				}
 			}
-			
 		}
 		else
 		{
-- 
GitLab