summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
authorJon Wolk <jwolk@lindenlab.com>2007-10-22 18:17:47 +0000
committerJon Wolk <jwolk@lindenlab.com>2007-10-22 18:17:47 +0000
commit94bcd2c47d7ba25693ae582e71e028142d3bc13b (patch)
tree058dd54f0085351cc9ffc35901efb1a221a56745 /indra/newview
parentaa8b0cbe690eef9ed4fb7f6f9e8cc75a0a073d76 (diff)
svn merge -r 71902:71933 svn+ssh://svn.lindenlab.com/svn/linden/branches/expire-group-voice-channels -> release. Reverted 2 changes from the merge that were useless code.
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/llimpanel.cpp108
-rw-r--r--indra/newview/llimpanel.h17
-rw-r--r--indra/newview/llimview.cpp78
-rw-r--r--indra/newview/llimview.h9
-rw-r--r--indra/newview/llvoiceclient.cpp6
5 files changed, 206 insertions, 12 deletions
diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp
index 3a947bcbff..b259b80116 100644
--- a/indra/newview/llimpanel.cpp
+++ b/indra/newview/llimpanel.cpp
@@ -79,6 +79,7 @@
const S32 LINE_HEIGHT = 16;
const S32 MIN_WIDTH = 200;
const S32 MIN_HEIGHT = 130;
+const U32 DEFAULT_RETRIES_COUNT = 3;
//
// Statics
@@ -502,6 +503,8 @@ void LLVoiceChannel::initClass()
LLVoiceChannelGroup::LLVoiceChannelGroup(const LLUUID& session_id, const LLString& session_name) :
LLVoiceChannel(session_id, session_name)
{
+ mRetries = DEFAULT_RETRIES_COUNT;
+ mIsRetrying = FALSE;
}
LLVoiceChannelGroup::~LLVoiceChannelGroup()
@@ -548,18 +551,92 @@ void LLVoiceChannelGroup::getChannelInfo()
}
}
+void LLVoiceChannelGroup::setChannelInfo(
+ const LLString& uri,
+ const LLString& credentials)
+{
+ setURI(uri);
+
+ mCredentials = credentials;
+
+ if (mState == STATE_NO_CHANNEL_INFO)
+ {
+ if(!mURI.empty() && !mCredentials.empty())
+ {
+ setState(STATE_READY);
+
+ // if we are supposed to be active, reconnect
+ // this will happen on initial connect, as we request credentials on first use
+ if (sCurrentVoiceChannel == this)
+ {
+ // just in case we got new channel info while active
+ // should move over to new channel
+ activate();
+ }
+ }
+ else
+ {
+ //*TODO: notify user
+ llwarns << "Received invalid credentials for channel " << mSessionName << llendl;
+ deactivate();
+ }
+ }
+ else if ( mIsRetrying )
+ {
+ // we have the channel info, just need to use it now
+ LLVoiceClient::getInstance()->setNonSpatialChannel(
+ mURI,
+ mCredentials);
+ }
+}
+
+void LLVoiceChannelGroup::handleStatusChange(EStatusType type)
+{
+ // status updates
+ switch(type)
+ {
+ case STATUS_JOINED:
+ mRetries = 3;
+ mIsRetrying = FALSE;
+ default:
+ break;
+ }
+
+ LLVoiceChannel::handleStatusChange(type);
+}
+
void LLVoiceChannelGroup::handleError(EStatusType status)
{
std::string notify;
switch(status)
{
- case ERROR_CHANNEL_LOCKED:
- case ERROR_CHANNEL_FULL:
+ case ERROR_CHANNEL_LOCKED:
+ case ERROR_CHANNEL_FULL:
notify = "VoiceChannelFull";
break;
- case ERROR_UNKNOWN:
+ case ERROR_NOT_AVAILABLE:
+ //clear URI and credentials
+ //set the state to be no info
+ //and activate
+ if ( mRetries > 0 )
+ {
+ mRetries--;
+ mIsRetrying = TRUE;
+ mIgnoreNextSessionLeave = TRUE;
+
+ getChannelInfo();
+ return;
+ }
+ else
+ {
+ notify = "VoiceChannelJoinFailed";
+ mRetries = DEFAULT_RETRIES_COUNT;
+ mIsRetrying = FALSE;
+ }
+
break;
- default:
+ case ERROR_UNKNOWN:
+ default:
break;
}
@@ -570,10 +647,27 @@ void LLVoiceChannelGroup::handleError(EStatusType status)
// echo to im window
gIMMgr->addMessage(mSessionID, LLUUID::null, SYSTEM_FROM, LLNotifyBox::getTemplateMessage(notify, mNotifyArgs).c_str());
}
-
+
LLVoiceChannel::handleError(status);
}
+void LLVoiceChannelGroup::setState(EState state)
+{
+ switch(state)
+ {
+ case STATE_RINGING:
+ if ( !mIsRetrying )
+ {
+ gIMMgr->addSystemMessage(mSessionID, "ringing", mNotifyArgs);
+ }
+
+ mState = state;
+ break;
+ default:
+ LLVoiceChannel::setState(state);
+ }
+}
+
//
// LLVoiceChannelProximal
//
@@ -710,7 +804,7 @@ void LLVoiceChannelP2P::handleStatusChange(EStatusType type)
break;
}
- LLVoiceChannelGroup::handleStatusChange(type);
+ LLVoiceChannel::handleStatusChange(type);
}
void LLVoiceChannelP2P::handleError(EStatusType type)
@@ -724,7 +818,7 @@ void LLVoiceChannelP2P::handleError(EStatusType type)
break;
}
- LLVoiceChannelGroup::handleError(type);
+ LLVoiceChannel::handleError(type);
}
void LLVoiceChannelP2P::activate()
diff --git a/indra/newview/llimpanel.h b/indra/newview/llimpanel.h
index 631dc5cca1..c1ad18dd3c 100644
--- a/indra/newview/llimpanel.h
+++ b/indra/newview/llimpanel.h
@@ -62,13 +62,15 @@ public:
LLVoiceChannel(const LLUUID& session_id, const LLString& session_name);
virtual ~LLVoiceChannel();
- void setChannelInfo(const LLString& uri, const LLString& credentials);
/*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal);
virtual void handleStatusChange(EStatusType status);
virtual void handleError(EStatusType status);
virtual void deactivate();
virtual void activate();
+ virtual void setChannelInfo(
+ const LLString& uri,
+ const LLString& credentials);
virtual void getChannelInfo();
virtual BOOL isActive();
virtual BOOL callStarted();
@@ -82,7 +84,7 @@ public:
static void initClass();
protected:
- void setState(EState state);
+ virtual void setState(EState state);
void setURI(LLString uri);
LLString mURI;
@@ -109,10 +111,21 @@ public:
LLVoiceChannelGroup(const LLUUID& session_id, const LLString& session_name);
virtual ~LLVoiceChannelGroup();
+ /*virtual*/ void handleStatusChange(EStatusType status);
/*virtual*/ void handleError(EStatusType status);
/*virtual*/ void activate();
/*virtual*/ void deactivate();
+ /*vritual*/ void setChannelInfo(
+ const LLString& uri,
+ const LLString& credentials);
/*virtual*/ void getChannelInfo();
+
+protected:
+ virtual void setState(EState state);
+
+private:
+ U32 mRetries;
+ BOOL mIsRetrying;
};
class LLVoiceChannelProximal : public LLVoiceChannel, public LLSingleton<LLVoiceChannelProximal>
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index dee1ed2bfd..a6e2a1393d 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -310,6 +310,7 @@ LLIMMgr::LLIMMgr() :
delete dummy_floater;
mPendingVoiceInvitations = LLSD::emptyMap();
+ mPendingAgentListUpdates = LLSD::emptyMap();
}
LLIMMgr::~LLIMMgr()
@@ -725,15 +726,41 @@ public:
if (floaterp)
{
+ //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.
floaterp->setSpeakersList(content["agents"]);
+ //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
+
+ //reapplying a user entrance will do nothing
+ //reapplying a user leaving will not have the user
+ //in our base. So it's all good
+ floaterp->updateSpeakersList(
+ gIMMgr->getPendingAgentListUpdates(mSessionID));
+
if ( mIsVoiceInvitiation )
{
floaterp->requestAutoConnect();
LLFloaterIMPanel::onClickStartCall(floaterp);
+ // always open IM window when connecting to voice
+ LLFloaterChatterBox::showInstance(TRUE);
}
}
+ gIMMgr->clearPendingAgentListUpdates(mSessionID);
if ( mIsVoiceInvitiation )
{
gIMMgr->clearPendingVoiceInviation(mSessionID);
@@ -779,6 +806,8 @@ void LLIMMgr::inviteUserResponse(S32 option, void* user_data)
{
im_floater->requestAutoConnect();
LLFloaterIMPanel::onClickStartCall(im_floater);
+ // always open IM window when connecting to voice
+ LLFloaterChatterBox::showInstance(TRUE);
}
gIMMgr->clearPendingVoiceInviation(invitep->mSessionID);
@@ -911,6 +940,41 @@ void LLIMMgr::clearPendingVoiceInviation(const LLUUID& session_id)
}
}
+LLSD LLIMMgr::getPendingAgentListUpdates(const LLUUID& session_id)
+{
+ if ( mPendingAgentListUpdates.has(session_id.asString()) )
+ {
+ return mPendingAgentListUpdates[session_id.asString()];
+ }
+ else
+ {
+ return LLSD();
+ }
+}
+
+void LLIMMgr::addPendingAgentListUpdates(
+ const LLUUID& session_id,
+ const LLSD& updates)
+{
+ LLSD::map_const_iterator iter;
+
+ for ( iter = updates.beginMap();
+ iter != updates.endMap();
+ iter++)
+ {
+ //we only want to include the last update for a given agent
+ mPendingAgentListUpdates[session_id.asString()][iter->first] =
+ iter->second;
+ }
+}
+
+void LLIMMgr::clearPendingAgentListUpdates(const LLUUID& session_id)
+{
+ if ( mPendingAgentListUpdates.has(session_id.asString()) )
+ {
+ mPendingAgentListUpdates.erase(session_id.asString());
+ }
+}
// create a floater and update internal representation for
// consistency. Returns the pointer, caller (the class instance since
@@ -1078,7 +1142,12 @@ public:
if (floaterp)
{
floaterp->setSpeakersList(body["agents"]);
+
+ //aply updates we've possibly received previously
+ floaterp->updateSpeakersList(
+ gIMMgr->getPendingAgentListUpdates(session_id));
}
+ gIMMgr->clearPendingAgentListUpdates(session_id);
}
else
{
@@ -1191,6 +1260,15 @@ public:
{
floaterp->updateSpeakersList(input["body"]["updates"]);
}
+ else
+ {
+ //we don't have a floater yet..something went wrong
+ //we are probably receiving an update here before
+ //a start or an acceptance of an invitation. Race condition.
+ gIMMgr->addPendingAgentListUpdates(
+ input["body"]["session_id"].asUUID(),
+ input["body"]["updates"]);
+ }
}
};
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index 5f7829cf42..f5356ef926 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -148,7 +148,13 @@ public:
static LLUUID computeSessionID(EInstantMessage dialog, const LLUUID& other_participant_id);
void clearPendingVoiceInviation(const LLUUID& session_id);
-
+
+ LLSD getPendingAgentListUpdates(const LLUUID& session_id);
+ void addPendingAgentListUpdates(
+ const LLUUID& sessioN_id,
+ const LLSD& updates);
+ void clearPendingAgentListUpdates(const LLUUID& session_id);
+
private:
class LLIMSessionInvite;
@@ -188,6 +194,7 @@ private:
BOOL mIMReceived;
LLSD mPendingVoiceInvitations;
+ LLSD mPendingAgentListUpdates;
};
diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp
index 3a74f1661b..f6f7ce7d5b 100644
--- a/indra/newview/llvoiceclient.cpp
+++ b/indra/newview/llvoiceclient.cpp
@@ -3954,8 +3954,10 @@ void LLVoiceClient::notifyStatusObservers(LLVoiceClientStatusObserver::EStatusTy
{
switch(mVivoxErrorStatusCode)
{
- case 20713: status = LLVoiceClientStatusObserver::ERROR_CHANNEL_FULL; break;
- case 20714: status = LLVoiceClientStatusObserver::ERROR_CHANNEL_LOCKED; break;
+ case 20713: status = LLVoiceClientStatusObserver::ERROR_CHANNEL_FULL; break;
+ case 20714: status = LLVoiceClientStatusObserver::ERROR_CHANNEL_LOCKED; break;
+ case 20715: status = LLVoiceClientStatusObserver::ERROR_NOT_AVAILABLE;
+ break;
}
// Reset the error code to make sure it won't be reused later by accident.