From 82b671dadc52ae2caca9c5b2ad0f1110c15754af Mon Sep 17 00:00:00 2001
From: Rider Linden <none@none>
Date: Wed, 29 Apr 2015 14:48:55 -0700
Subject: [PATCH] Convert IM invitation to coroutines.

---
 indra/newview/llimview.cpp | 328 ++++++++++++++++---------------------
 indra/newview/llimview.h   |   4 +
 2 files changed, 148 insertions(+), 184 deletions(-)

diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 5d3a11e2451..abf206d2d77 100755
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -69,6 +69,7 @@
 #include "llconversationlog.h"
 #include "message.h"
 #include "llviewerregion.h"
+#include "llcorehttputil.h"
 
 
 const static std::string ADHOC_NAME_SUFFIX(" Conference");
@@ -79,6 +80,10 @@ const static std::string NEARBY_P2P_BY_AGENT("nearby_P2P_by_agent");
 /** Timeout of outgoing session initialization (in seconds) */
 const static U32 SESSION_INITIALIZATION_TIMEOUT = 30;
 
+void startConfrenceCoro(LLCoros::self& self, std::string url, LLUUID tempSessionId, LLUUID creatorId, LLUUID otherParticipantId, LLSD agents);
+void chatterBoxInvitationCoro(LLCoros::self& self, std::string url, LLUUID sessionId, LLIMMgr::EInvitationType invitationType);
+void start_deprecated_conference_chat(const LLUUID& temp_session_id, const LLUUID& creator_id, const LLUUID& other_participant_id, const LLSD& agents_to_invite);
+
 std::string LLCallDialogManager::sPreviousSessionlName = "";
 LLIMModel::LLIMSession::SType LLCallDialogManager::sPreviousSessionType = LLIMModel::LLIMSession::P2P_SESSION;
 std::string LLCallDialogManager::sCurrentSessionlName = "";
@@ -110,7 +115,7 @@ void process_dnd_im(const LLSD& notification)
 {
     LLSD data = notification["substitutions"];
     LLUUID sessionID = data["SESSION_ID"].asUUID();
-	LLUUID fromID = data["FROM_ID"].asUUID();
+    LLUUID fromID = data["FROM_ID"].asUUID();
 
     //re-create the IM session if needed 
     //(when coming out of DND mode upon app restart)
@@ -131,12 +136,10 @@ void process_dnd_im(const LLSD& notification)
             fromID, 
             false, 
             false); //will need slight refactor to retrieve whether offline message or not (assume online for now)
-		}
-
-	notify_of_message(data, true);
     }
 
-
+    notify_of_message(data, true);
+}
 
 
 static void on_avatar_name_cache_toast(const LLUUID& agent_id,
@@ -387,6 +390,130 @@ void on_new_message(const LLSD& msg)
 	notify_of_message(msg, false);
 }
 
+void startConfrenceCoro(LLCoros::self& self, std::string url,
+    LLUUID tempSessionId, LLUUID creatorId, LLUUID otherParticipantId, LLSD agents)
+{
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("TwitterConnect", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+    LLSD postData;
+    postData["method"] = "start conference";
+    postData["session-id"] = tempSessionId;
+    postData["params"] = agents;
+
+    LLSD result = httpAdapter->postAndYield(self, httpRequest, url, postData);
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroHandler::getStatusFromLLSD(httpResults);
+
+    if (!status)
+    {
+        LL_WARNS("LLIMModel") << "Failed to start conference" << LL_ENDL;
+        //try an "old school" way.
+        // *TODO: What about other error status codes?  4xx 5xx?
+        if (status == LLCore::HttpStatus(HTTP_BAD_REQUEST))
+        {
+            start_deprecated_conference_chat(
+                tempSessionId,
+                creatorId,
+                otherParticipantId,
+                agents);
+        }
+
+        //else throw an error back to the client?
+        //in theory we should have just have these error strings
+        //etc. set up in this file as opposed to the IMMgr,
+        //but the error string were unneeded here previously
+        //and it is not worth the effort switching over all
+        //the possible different language translations
+    }
+}
+
+void chatterBoxInvitationCoro(LLCoros::self& self, std::string url, LLUUID sessionId, LLIMMgr::EInvitationType invitationType)
+{
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("TwitterConnect", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+    LLSD postData;
+    postData["method"] = "accept invitation";
+    postData["session-id"] = sessionId;
+
+    LLSD result = httpAdapter->postAndYield(self, httpRequest, url, postData);
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroHandler::getStatusFromLLSD(httpResults);
+
+    if (!gIMMgr)
+    {
+        LL_WARNS("") << "Global IM Manager is NULL" << LL_ENDL;
+        return;
+    }
+
+    if (!status)
+    {
+        LL_WARNS("LLIMModel") << "Bad HTTP response in chatterBoxInvitationCoro" << LL_ENDL;
+        //throw something back to the viewer here?
+
+        gIMMgr->clearPendingAgentListUpdates(sessionId);
+        gIMMgr->clearPendingInvitation(sessionId);
+
+        if (status == LLCore::HttpStatus(HTTP_NOT_FOUND))
+        {
+            static const std::string error_string("session_does_not_exist_error");
+            gIMMgr->showSessionStartError(error_string, sessionId);
+        }
+        return;
+    }
+
+    result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+
+    LLIMSpeakerMgr* speakerMgr = LLIMModel::getInstance()->getSpeakerManager(sessionId);
+    if (speakerMgr)
+    {
+        //we've accepted our invitation
+        //and received a list of agents that were
+        //currently in the session when the reply was sent
+        //to us.  Now, it is possible that there were some agents
+        //to slip in/out between when that message was sent to us
+        //and now.
+
+        //the agent list updates we've received have been
+        //accurate from the time we were added to the session
+        //but unfortunately, our base that we are receiving here
+        //may not be the most up to date.  It was accurate at
+        //some point in time though.
+        speakerMgr->setSpeakers(result);
+
+        //we now have our base of users in the session
+        //that was accurate at some point, but maybe not now
+        //so now we apply all of the updates we've received
+        //in case of race conditions
+        speakerMgr->updateSpeakers(gIMMgr->getPendingAgentListUpdates(sessionId));
+    }
+
+    if (LLIMMgr::INVITATION_TYPE_VOICE == invitationType)
+    {
+        gIMMgr->startCall(sessionId, LLVoiceChannel::INCOMING_CALL);
+    }
+
+    if ((invitationType == LLIMMgr::INVITATION_TYPE_VOICE
+        || invitationType == LLIMMgr::INVITATION_TYPE_IMMEDIATE)
+        && LLIMModel::getInstance()->findIMSession(sessionId))
+    {
+        // TODO remove in 2010, for voice calls we do not open an IM window
+        //LLFloaterIMSession::show(mSessionID);
+    }
+
+    gIMMgr->clearPendingAgentListUpdates(sessionId);
+    gIMMgr->clearPendingInvitation(sessionId);
+
+}
+
+
 LLIMModel::LLIMModel() 
 {
 	addNewMsgCallback(boost::bind(&LLFloaterIMSession::newIMCallback, _1));
@@ -1459,54 +1586,6 @@ void start_deprecated_conference_chat(
 	delete[] bucket;
 }
 
-class LLStartConferenceChatResponder : public LLHTTPClient::Responder
-{
-	LOG_CLASS(LLStartConferenceChatResponder);
-public:
-	LLStartConferenceChatResponder(
-		const LLUUID& temp_session_id,
-		const LLUUID& creator_id,
-		const LLUUID& other_participant_id,
-		const LLSD& agents_to_invite)
-	{
-		mTempSessionID = temp_session_id;
-		mCreatorID = creator_id;
-		mOtherParticipantID = other_participant_id;
-		mAgents = agents_to_invite;
-	}
-
-protected:
-	virtual void httpFailure()
-	{
-		//try an "old school" way.
-		// *TODO: What about other error status codes?  4xx 5xx?
-		if ( getStatus() == HTTP_BAD_REQUEST )
-		{
-			start_deprecated_conference_chat(
-				mTempSessionID,
-				mCreatorID,
-				mOtherParticipantID,
-				mAgents);
-		}
-
-		LL_WARNS() << dumpResponse() << LL_ENDL;
-
-		//else throw an error back to the client?
-		//in theory we should have just have these error strings
-		//etc. set up in this file as opposed to the IMMgr,
-		//but the error string were unneeded here previously
-		//and it is not worth the effort switching over all
-		//the possible different language translations
-	}
-
-private:
-	LLUUID mTempSessionID;
-	LLUUID mCreatorID;
-	LLUUID mOtherParticipantID;
-
-	LLSD mAgents;
-};
-
 // Returns true if any messages were sent, false otherwise.
 // Is sort of equivalent to "does the server need to do anything?"
 bool LLIMModel::sendStartSession(
@@ -1543,20 +1622,10 @@ bool LLIMModel::sendStartSession(
 		{
 			std::string url = region->getCapability(
 				"ChatSessionRequest");
-			LLSD data;
-			data["method"] = "start conference";
-			data["session-id"] = temp_session_id;
 
-			data["params"] = agents;
-
-			LLHTTPClient::post(
-				url,
-				data,
-				new LLStartConferenceChatResponder(
-					temp_session_id,
-					gAgent.getID(),
-					other_participant_id,
-					data["params"]));
+            LLCoros::instance().launch("startConfrenceCoro",
+                boost::bind(&startConfrenceCoro, _1, url,
+                temp_session_id, gAgent.getID(), other_participant_id, agents));
 		}
 		else
 		{
@@ -1574,97 +1643,6 @@ bool LLIMModel::sendStartSession(
 	return false;
 }
 
-//
-// Helper Functions
-//
-
-class LLViewerChatterBoxInvitationAcceptResponder :
-	public LLHTTPClient::Responder
-{
-	LOG_CLASS(LLViewerChatterBoxInvitationAcceptResponder);
-public:
-	LLViewerChatterBoxInvitationAcceptResponder(
-		const LLUUID& session_id,
-		LLIMMgr::EInvitationType invitation_type)
-	{
-		mSessionID = session_id;
-		mInvitiationType = invitation_type;
-	}
-
-private:
-	void httpSuccess()
-	{
-		const LLSD& content = getContent();
-		if (!content.isMap())
-		{
-			failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
-			return;
-		}
-		if ( gIMMgr)
-		{
-			LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
-			if (speaker_mgr)
-			{
-				//we've accepted our invitation
-				//and received a list of agents that were
-				//currently in the session when the reply was sent
-				//to us.  Now, it is possible that there were some agents
-				//to slip in/out between when that message was sent to us
-				//and now.
-
-				//the agent list updates we've received have been
-				//accurate from the time we were added to the session
-				//but unfortunately, our base that we are receiving here
-				//may not be the most up to date.  It was accurate at
-				//some point in time though.
-				speaker_mgr->setSpeakers(content);
-
-				//we now have our base of users in the session
-				//that was accurate at some point, but maybe not now
-				//so now we apply all of the udpates we've received
-				//in case of race conditions
-				speaker_mgr->updateSpeakers(gIMMgr->getPendingAgentListUpdates(mSessionID));
-			}
-
-			if (LLIMMgr::INVITATION_TYPE_VOICE == mInvitiationType)
-			{
-				gIMMgr->startCall(mSessionID, LLVoiceChannel::INCOMING_CALL);
-			}
-
-			if ((mInvitiationType == LLIMMgr::INVITATION_TYPE_VOICE 
-				|| mInvitiationType == LLIMMgr::INVITATION_TYPE_IMMEDIATE)
-				&& LLIMModel::getInstance()->findIMSession(mSessionID))
-			{
-				// TODO remove in 2010, for voice calls we do not open an IM window
-				//LLFloaterIMSession::show(mSessionID);
-			}
-
-			gIMMgr->clearPendingAgentListUpdates(mSessionID);
-			gIMMgr->clearPendingInvitation(mSessionID);
-		}
-	}
-
-	void httpFailure()
-	{
-		LL_WARNS() << dumpResponse() << LL_ENDL;
-		//throw something back to the viewer here?
-		if ( gIMMgr )
-		{
-			gIMMgr->clearPendingAgentListUpdates(mSessionID);
-			gIMMgr->clearPendingInvitation(mSessionID);
-			if ( HTTP_NOT_FOUND == getStatus() )
-			{
-				static const std::string error_string("session_does_not_exist_error");
-				gIMMgr->showSessionStartError(error_string, mSessionID);
-			}
-		}
-	}
-
-private:
-	LLUUID mSessionID;
-	LLIMMgr::EInvitationType mInvitiationType;
-};
-
 
 // the other_participant_id is either an agent_id, a group_id, or an inventory
 // folder item_id (collection of calling cards)
@@ -2490,15 +2468,9 @@ void LLIncomingCallDialog::processCallResponse(S32 response, const LLSD &payload
 
 			if (voice)
 			{
-				LLSD data;
-				data["method"] = "accept invitation";
-				data["session-id"] = session_id;
-				LLHTTPClient::post(
-					url,
-					data,
-					new LLViewerChatterBoxInvitationAcceptResponder(
-						session_id,
-						inv_type));
+                LLCoros::instance().launch("chatterBoxInvitationCoro",
+                    boost::bind(&chatterBoxInvitationCoro, _1, url,
+                    session_id, inv_type));
 
 				// send notification message to the corresponding chat 
 				if (payload["notify_box_type"].asString() == "VoiceInviteGroup" || payload["notify_box_type"].asString() == "VoiceInviteAdHoc")
@@ -2583,15 +2555,9 @@ bool inviteUserResponse(const LLSD& notification, const LLSD& response)
 				std::string url = gAgent.getRegion()->getCapability(
 					"ChatSessionRequest");
 
-				LLSD data;
-				data["method"] = "accept invitation";
-				data["session-id"] = session_id;
-				LLHTTPClient::post(
-					url,
-					data,
-					new LLViewerChatterBoxInvitationAcceptResponder(
-						session_id,
-						inv_type));
+                LLCoros::instance().launch("chatterBoxInvitationCoro",
+                    boost::bind(&chatterBoxInvitationCoro, _1, url,
+                    session_id, inv_type));
 			}
 		}
 		break;
@@ -3681,15 +3647,9 @@ class LLViewerChatterBoxInvitation : public LLHTTPNode
 
 			if ( url != "" )
 			{
-				LLSD data;
-				data["method"] = "accept invitation";
-				data["session-id"] = session_id;
-				LLHTTPClient::post(
-					url,
-					data,
-					new LLViewerChatterBoxInvitationAcceptResponder(
-						session_id,
-						LLIMMgr::INVITATION_TYPE_INSTANT_MESSAGE));
+                LLCoros::instance().launch("chatterBoxInvitationCoro",
+                    boost::bind(&chatterBoxInvitationCoro, _1, url,
+                    session_id, LLIMMgr::INVITATION_TYPE_INSTANT_MESSAGE));
 			}
 		} //end if invitation has instant message
 		else if ( input["body"].has("voice") )
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index f92eff48458..41a8813acb2 100755
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -34,6 +34,9 @@
 #include "lllogchat.h"
 #include "llvoicechannel.h"
 
+#include "llcoros.h"
+#include "lleventcoro.h"
+
 class LLAvatarName;
 class LLFriendObserver;
 class LLCallDialogManager;	
@@ -292,6 +295,7 @@ class LLIMModel :  public LLSingleton<LLIMModel>
 	 * Add message to a list of message associated with session specified by session_id
 	 */
 	bool addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text);
+
 };
 
 class LLIMSessionObserver
-- 
GitLab