summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoxanne Skelly <roxanne@roxiware.com>2024-05-03 15:07:20 -0700
committerGitHub <noreply@github.com>2024-05-03 15:07:20 -0700
commit818c8c6deaa755c02b64fb03766ee03d66021968 (patch)
tree75bf206410bff1c655a15dd80ca05abdab81f581
parentb425165addbe1c141e050556ff4aa18c8d042dab (diff)
parentcce51e98b188371fa864291f943452188d0e0a94 (diff)
Merge pull request #1401 from secondlife/webrtc-voice
-rw-r--r--autobuild.xml12
-rw-r--r--indra/llwebrtc/llwebrtc.cpp22
-rw-r--r--indra/llwebrtc/llwebrtc_impl.h2
-rw-r--r--indra/newview/app_settings/settings.xml4
-rw-r--r--indra/newview/llimview.cpp180
-rw-r--r--indra/newview/llimview.h9
-rw-r--r--indra/newview/llspeakers.cpp2
-rw-r--r--indra/newview/llspeakers.h1
-rw-r--r--indra/newview/llvoicechannel.cpp20
-rw-r--r--indra/newview/llvoiceclient.cpp12
-rw-r--r--indra/newview/llvoiceclient.h2
-rw-r--r--indra/newview/llvoicevivox.cpp16
-rw-r--r--indra/newview/llvoicewebrtc.cpp149
-rw-r--r--indra/newview/llvoicewebrtc.h22
-rw-r--r--indra/newview/skins/default/xui/en/floater_incoming_call.xml2
15 files changed, 311 insertions, 144 deletions
diff --git a/autobuild.xml b/autobuild.xml
index f9c99514a1..625fe72449 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -2901,11 +2901,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>creds</key>
<string>github</string>
<key>hash</key>
- <string>a49fb3bb8aaf8325e7c6c4b6036db3da16afa2c9</string>
+ <string>21e31d2c2fffdb59d8f50b80db079f86f2df2483</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/3p-webrtc-build/releases/download/m114.5735.08.53/webrtc-m114.5735.08.53.8337236647-darwin64-8337236647.tar.zst</string>
+ <string>https://github.com/secondlife/3p-webrtc-build/releases/download/m114.5735.08.58/webrtc-m114.5735.08.58.8716173807-darwin64-8716173807.tar.zst</string>
</map>
<key>name</key>
<string>darwin64</string>
@@ -2915,11 +2915,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
- <string>598baa054f63624a8e16883541c1f3dc7aa15a8a</string>
+ <string>600cabb49a889db3a29f2910f5bda08f28dd04c8</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/3p-webrtc-build/releases/download/m114.5735.08.53/webrtc-m114.5735.08.53.8337236647-linux64-8337236647.tar.zst</string>
+ <string>https://github.com/secondlife/3p-webrtc-build/releases/download/m114.5735.08.58/webrtc-m114.5735.08.58.8716173807-linux64-8716173807.tar.zst</string>
</map>
<key>name</key>
<string>linux64</string>
@@ -2931,11 +2931,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>creds</key>
<string>github</string>
<key>hash</key>
- <string>59d5f2e40612ab7b0b1a5da8ba288f48d5979216</string>
+ <string>915c9face95efcc6da240aa2c4f8e6c4aa803af8</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/3p-webrtc-build/releases/download/m114.5735.08.53/webrtc-m114.5735.08.53.8337236647-windows64-8337236647.tar.zst</string>
+ <string>https://github.com/secondlife/3p-webrtc-build/releases/download/m114.5735.08.58/webrtc-m114.5735.08.58.8716173807-windows64-8716173807.tar.zst</string>
</map>
<key>name</key>
<string>windows64</string>
diff --git a/indra/llwebrtc/llwebrtc.cpp b/indra/llwebrtc/llwebrtc.cpp
index eb9bb65e67..97c04ae446 100644
--- a/indra/llwebrtc/llwebrtc.cpp
+++ b/indra/llwebrtc/llwebrtc.cpp
@@ -652,6 +652,13 @@ LLWebRTCPeerConnectionImpl::LLWebRTCPeerConnectionImpl() :
{
}
+LLWebRTCPeerConnectionImpl::~LLWebRTCPeerConnectionImpl()
+{
+ terminate();
+ mSignalingObserverList.clear();
+ mDataObserverList.clear();
+}
+
//
// LLWebRTCPeerConnection interface
//
@@ -670,9 +677,6 @@ void LLWebRTCPeerConnectionImpl::terminate()
rtc::scoped_refptr<webrtc::MediaStreamInterface> localStream;
mLocalStream.swap(localStream);
- mSignalingObserverList.clear();
- mDataObserverList.clear();
-
mWebRTCImpl->PostSignalingTask(
[=]()
{
@@ -735,6 +739,10 @@ bool LLWebRTCPeerConnectionImpl::initializeConnection(const LLWebRTCPeerConnecti
else
{
RTC_LOG(LS_ERROR) << __FUNCTION__ << "Error creating peer connection: " << error_or_peer_connection.error().message();
+ for (auto &observer : mSignalingObserverList)
+ {
+ observer->OnRenegotiationNeeded();
+ }
return;
}
@@ -758,7 +766,7 @@ bool LLWebRTCPeerConnectionImpl::initializeConnection(const LLWebRTCPeerConnecti
rtc::scoped_refptr<webrtc::AudioTrackInterface> audio_track(
mPeerConnectionFactory->CreateAudioTrack("SLAudio", mPeerConnectionFactory->CreateAudioSource(audioOptions).get()));
- audio_track->set_enabled(true);
+ audio_track->set_enabled(false);
mLocalStream->AddTrack(audio_track);
mPeerConnection->AddTrack(audio_track, {"SLStream"});
@@ -949,6 +957,10 @@ void LLWebRTCPeerConnectionImpl::OnRemoveTrack(rtc::scoped_refptr<webrtc::RtpRec
void LLWebRTCPeerConnectionImpl::OnDataChannel(rtc::scoped_refptr<webrtc::DataChannelInterface> channel)
{
+ if (mDataChannel)
+ {
+ mDataChannel->UnregisterObserver();
+ }
mDataChannel = channel;
channel->RegisterObserver(this);
}
@@ -991,8 +1003,6 @@ void LLWebRTCPeerConnectionImpl::OnConnectionChange(webrtc::PeerConnectionInterf
{
case webrtc::PeerConnectionInterface::PeerConnectionState::kConnected:
{
- mWebRTCImpl->setRecording(true);
-
mWebRTCImpl->PostWorkerTask([this]() {
for (auto &observer : mSignalingObserverList)
{
diff --git a/indra/llwebrtc/llwebrtc_impl.h b/indra/llwebrtc/llwebrtc_impl.h
index e1031099c7..984aaef734 100644
--- a/indra/llwebrtc/llwebrtc_impl.h
+++ b/indra/llwebrtc/llwebrtc_impl.h
@@ -276,7 +276,7 @@ class LLWebRTCPeerConnectionImpl : public LLWebRTCPeerConnectionInterface,
{
public:
LLWebRTCPeerConnectionImpl();
- ~LLWebRTCPeerConnectionImpl() {}
+ ~LLWebRTCPeerConnectionImpl();
void init(LLWebRTCImpl * webrtc_impl);
void terminate();
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 0de6db0d65..3ac1844f8e 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -15155,13 +15155,13 @@
<key>VoiceServerType</key>
<map>
<key>Comment</key>
- <string>The type of voice server to connect to.</string>
+ <string>The type of voice server to use for group, conference, and p2p calls.</string>
<key>Persist</key>
<integer>0</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
- <string>webrtc</string>
+ <string/>
</map>
<key>WLSkyDetail</key>
<map>
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 9c8fcd3283..a1fb49c277 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -104,7 +104,7 @@ void startConferenceCoro(std::string url, LLUUID tempSessionId, LLUUID creatorId
void startP2PVoiceCoro(std::string url, LLUUID tempSessionId, LLUUID creatorId, LLUUID otherParticipantId);
-void chatterBoxInvitationCoro(std::string url, LLUUID sessionId, LLIMMgr::EInvitationType invitationType);
+void chatterBoxInvitationCoro(std::string url, LLUUID sessionId, LLIMMgr::EInvitationType invitationType, const LLSD& voiceChannelInfo);
void chatterBoxHistoryCoro(std::string url, LLUUID sessionId, std::string from, std::string message, U32 timestamp);
void start_deprecated_conference_chat(const LLUUID& temp_session_id, const LLUUID& creator_id, const LLUUID& other_participant_id, const LLSD& agents_to_invite);
@@ -425,7 +425,14 @@ void startConferenceCoro(std::string url,
postData["session-id"] = tempSessionId;
postData["params"] = agents;
LLSD altParams;
- altParams["voice_server_type"] = gSavedSettings.getString("VoiceServerType");
+ std::string voice_server_type = gSavedSettings.getString("VoiceServerType");
+ if (voice_server_type.empty())
+ {
+ // default to the server type associated with the region we're on.
+ LLVoiceVersionInfo versionInfo = LLVoiceClient::getInstance()->getVersion();
+ voice_server_type = versionInfo.internalVoiceServerType;
+ }
+ altParams["voice_server_type"] = voice_server_type;
postData["alt_params"] = altParams;
LLSD result = httpAdapter->postAndSuspend(httpRequest, url, postData);
@@ -467,7 +474,14 @@ void startP2PVoiceCoro(std::string url, LLUUID sessionID, LLUUID creatorId, LLUU
postData["session-id"] = sessionID;
postData["params"] = otherParticipantId;
LLSD altParams;
- altParams["voice_server_type"] = gSavedSettings.getString("VoiceServerType");
+ std::string voice_server_type = gSavedSettings.getString("VoiceServerType");
+ if (voice_server_type.empty())
+ {
+ // default to the server type associated with the region we're on.
+ LLVoiceVersionInfo versionInfo = LLVoiceClient::getInstance()->getVersion();
+ voice_server_type = versionInfo.internalVoiceServerType;
+ }
+ altParams["voice_server_type"] = voice_server_type;
postData["alt_params"] = altParams;
LLSD result = httpAdapter->postAndSuspend(httpRequest, url, postData);
@@ -488,7 +502,7 @@ void startP2PVoiceCoro(std::string url, LLUUID sessionID, LLUUID creatorId, LLUU
}
}
-void chatterBoxInvitationCoro(std::string url, LLUUID sessionId, LLIMMgr::EInvitationType invitationType)
+void chatterBoxInvitationCoro(std::string url, LLUUID sessionId, LLIMMgr::EInvitationType invitationType, const LLSD& voiceChannelInfo)
{
LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
@@ -554,7 +568,7 @@ void chatterBoxInvitationCoro(std::string url, LLUUID sessionId, LLIMMgr::EInvit
if (LLIMMgr::INVITATION_TYPE_VOICE == invitationType)
{
- gIMMgr->startCall(sessionId, LLVoiceChannel::INCOMING_CALL);
+ gIMMgr->startCall(sessionId, LLVoiceChannel::INCOMING_CALL, voiceChannelInfo);
}
if ((invitationType == LLIMMgr::INVITATION_TYPE_VOICE
@@ -698,8 +712,8 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id,
const std::string& name,
const EInstantMessage& type,
const LLUUID& other_participant_id,
+ const LLSD& voice_channel_info,
const uuid_vec_t& ids,
- const LLSD& voiceChannelInfo,
bool has_offline_msg)
: mSessionID(session_id),
mName(name),
@@ -710,56 +724,30 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id,
mOtherParticipantID(other_participant_id),
mInitialTargetIDs(ids),
mVoiceChannel(NULL),
+ mP2PAsAdhocCall(false),
mSpeakers(NULL),
mSessionInitialized(false),
mCallBackEnabled(true),
mTextIMPossible(true),
mStartCallOnInitialize(false),
- mStartedAsIMCall(!voiceChannelInfo.isUndefined()),
+ mStartedAsIMCall(!voice_channel_info.isUndefined()),
mIsDNDsend(false),
mAvatarNameCacheConnection()
{
// set P2P type by default
mSessionType = P2P_SESSION;
- bool p2pAsAdhocCall = false;
if (IM_NOTHING_SPECIAL == mType || IM_SESSION_P2P_INVITE == mType)
- {
- LLVoiceP2POutgoingCallInterface *outgoingInterface =
- LLVoiceClient::getInstance()->getOutgoingCallInterface(voiceChannelInfo);
-
- if (outgoingInterface)
- {
- // only use LLVoiceChannelP2P if the provider can handle the special P2P interface,
- // which uses the voice server to relay calls and invites. Otherwise,
- // we use the group voice provider.
- mVoiceChannel = new LLVoiceChannelP2P(session_id, name, other_participant_id, outgoingInterface);
- }
- else
- {
- p2pAsAdhocCall = true;
- mVoiceChannel = new LLVoiceChannelGroup(session_id, name, true);
- }
+ {
+ mP2PAsAdhocCall = (LLVoiceClient::getInstance()->getOutgoingCallInterface(voice_channel_info) == NULL);
}
else
{
// determine whether it is group or conference session
- if (gAgent.isInGroup(mSessionID))
- {
- mSessionType = GROUP_SESSION;
- mVoiceChannel = new LLVoiceChannelGroup(session_id, name, false);
- }
- else
- {
- mSessionType = ADHOC_SESSION;
- mVoiceChannel = new LLVoiceChannelGroup(session_id, name, false);
- }
+ mSessionType = gAgent.isInGroup(mSessionID) ? GROUP_SESSION : ADHOC_SESSION;
}
- mVoiceChannelStateChangeConnection = mVoiceChannel->setStateChangedCallback(boost::bind(&LLIMSession::onVoiceChannelStateChanged, this, _1, _2, _3));
- mVoiceChannel->setChannelInfo(voiceChannelInfo);
-
- mSpeakers = new LLIMSpeakerMgr(mVoiceChannel);
+ initVoiceChannel(voice_channel_info);
// All participants will be added to the list of people we've recently interacted with.
@@ -769,7 +757,7 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id,
//we need to wait for session initialization for outgoing ad-hoc and group chat session
//correct session id for initiated ad-hoc chat will be received from the server
- if (!LLIMModel::getInstance()->sendStartSession(mSessionID, mOtherParticipantID, mInitialTargetIDs, mType, p2pAsAdhocCall))
+ if (!LLIMModel::getInstance()->sendStartSession(mSessionID, mOtherParticipantID, mInitialTargetIDs, mType, mP2PAsAdhocCall))
{
//we don't need to wait for any responses
//so we're already initialized
@@ -799,6 +787,68 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id,
}
}
+void LLIMModel::LLIMSession::initVoiceChannel(const LLSD& voiceChannelInfo)
+{
+ mVoiceChannelStateChangeConnection.disconnect();
+
+ if (mVoiceChannel)
+ {
+ mVoiceChannel->deactivate();
+
+ delete mVoiceChannel;
+ mVoiceChannel = NULL;
+ }
+ mP2PAsAdhocCall = false;
+ if (IM_NOTHING_SPECIAL == mType || IM_SESSION_P2P_INVITE == mType)
+ {
+ LLVoiceP2POutgoingCallInterface *outgoingInterface = LLVoiceClient::getInstance()->getOutgoingCallInterface(voiceChannelInfo);
+
+ if (outgoingInterface)
+ {
+ // only use LLVoiceChannelP2P if the provider can handle the special P2P interface,
+ // which uses the voice server to relay calls and invites. Otherwise,
+ // we use the group voice provider.
+ mVoiceChannel = new LLVoiceChannelP2P(mSessionID, mName, mOtherParticipantID, outgoingInterface);
+ }
+ else
+ {
+ mP2PAsAdhocCall = true;
+ mVoiceChannel = new LLVoiceChannelGroup(mSessionID, mName, true);
+ }
+ }
+ else
+ {
+ // determine whether it is group or conference session
+ if (mSessionType == GROUP_SESSION)
+ {
+ mSessionType = GROUP_SESSION;
+ mVoiceChannel = new LLVoiceChannelGroup(mSessionID, mName, false);
+ }
+ else if (mSessionType == ADHOC_SESSION)
+ {
+ mSessionType = ADHOC_SESSION;
+ mVoiceChannel = new LLVoiceChannelGroup(mSessionID, mName, false);
+ }
+ else
+ {
+ LL_WARNS("Voice") << "Invalid Session Type when initializing voice channel: " << mSessionType << LL_ENDL;
+ return;
+ }
+ }
+
+ mVoiceChannelStateChangeConnection =
+ mVoiceChannel->setStateChangedCallback(boost::bind(&LLIMSession::onVoiceChannelStateChanged, this, _1, _2, _3));
+
+ if (!mSpeakers)
+ {
+ mSpeakers = new LLIMSpeakerMgr(mVoiceChannel);
+ }
+ else
+ {
+ mSpeakers->setVoiceChannel(mVoiceChannel);
+ }
+}
+
void LLIMModel::LLIMSession::onAdHocNameCache(const LLAvatarName& av_name)
{
mAvatarNameCacheConnection.disconnect();
@@ -902,7 +952,7 @@ void LLIMModel::LLIMSession::onVoiceChannelStateChanged(const LLVoiceChannel::ES
break;
}
// Update speakers list when connected
- if (LLVoiceChannel::STATE_CONNECTED == new_state)
+ if (mSpeakers && LLVoiceChannel::STATE_CONNECTED == new_state)
{
mSpeakers->update(true);
}
@@ -934,7 +984,10 @@ void LLIMModel::LLIMSession::sessionInitReplyReceived(const LLUUID& new_session_
if (new_session_id != mSessionID)
{
mSessionID = new_session_id;
- mVoiceChannel->updateSessionID(new_session_id);
+ if (mVoiceChannel)
+ {
+ mVoiceChannel->updateSessionID(new_session_id);
+ }
}
}
@@ -1506,7 +1559,7 @@ bool LLIMModel::newSession(const LLUUID& session_id, const std::string& name, co
return false;
}
- LLIMSession* session = new LLIMSession(session_id, name, type, other_participant_id, ids, voiceChannelInfo, has_offline_msg);
+ LLIMSession *session = new LLIMSession(session_id, name, type, other_participant_id, voiceChannelInfo, ids, has_offline_msg);
mId2SessionMap[session_id] = session;
// When notifying observer, name of session is used instead of "name", because they may not be the
@@ -1770,7 +1823,7 @@ EInstantMessage LLIMModel::getType(const LLUUID& session_id) const
return session->mType;
}
-LLVoiceChannel* LLIMModel::getVoiceChannel( const LLUUID& session_id ) const
+LLVoiceChannel* LLIMModel::getVoiceChannel( const LLUUID& session_id, const LLSD& voice_channel_info ) const
{
LLIMSession* session = findIMSession(session_id);
if (!session)
@@ -1778,6 +1831,14 @@ LLVoiceChannel* LLIMModel::getVoiceChannel( const LLUUID& session_id ) const
LL_WARNS() << "session " << session_id << "does not exist " << LL_ENDL;
return NULL;
}
+ if (IM_NOTHING_SPECIAL == session->mType || IM_SESSION_P2P_INVITE == session->mType)
+ {
+ LLVoiceP2POutgoingCallInterface *outgoingInterface = LLVoiceClient::getInstance()->getOutgoingCallInterface(voice_channel_info);
+ if ((outgoingInterface != NULL) != (dynamic_cast<LLVoiceChannelP2P *>(session->mVoiceChannel) != NULL))
+ {
+ session->initVoiceChannel(voice_channel_info);
+ }
+ }
return session->mVoiceChannel;
}
@@ -2119,7 +2180,7 @@ bool LLIMModel::sendStartSession(
//we also need to wait for reply from the server in case of ad-hoc chat (we'll get new session id)
return true;
}
- else if ((dialog == IM_SESSION_P2P_INVITE) || (dialog == IM_NOTHING_SPECIAL))
+ else if (p2p_as_adhoc_call && ((dialog == IM_SESSION_P2P_INVITE) || (dialog == IM_NOTHING_SPECIAL)))
{
LLViewerRegion *region = gAgent.getRegion();
if (region)
@@ -2740,7 +2801,7 @@ void LLIncomingCallDialog::onLifetimeExpired()
LLUUID session_id = mPayload["session_id"].asUUID();
gIMMgr->clearPendingAgentListUpdates(session_id);
gIMMgr->clearPendingInvitation(session_id);
- closeFloater();
+ LLIncomingCallDialog::onReject(this);
}
}
@@ -2929,7 +2990,7 @@ void LLIncomingCallDialog::processCallResponse(S32 response, const LLSD &payload
if (voice)
{
- gIMMgr->startCall(session_id, LLVoiceChannel::INCOMING_CALL);
+ gIMMgr->startCall(session_id, LLVoiceChannel::INCOMING_CALL, payload["voice_channel_info"]);
}
else
{
@@ -2983,8 +3044,7 @@ void LLIncomingCallDialog::processCallResponse(S32 response, const LLSD &payload
if (voice)
{
LLCoros::instance().launch("chatterBoxInvitationCoro",
- boost::bind(&chatterBoxInvitationCoro, url,
- session_id, inv_type));
+ boost::bind(&chatterBoxInvitationCoro, url, session_id, inv_type, payload["voice_channel_info"]));
// send notification message to the corresponding chat
if (payload["notify_box_type"].asString() == "VoiceInviteGroup" || payload["notify_box_type"].asString() == "VoiceInviteAdHoc")
@@ -3468,7 +3528,6 @@ void LLIMMgr::inviteToSession(
payload["caller_name"] = caller_name;
payload["type"] = type;
payload["inv_type"] = inv_type;
- payload["voice_channel_info"] = voice_channel_info;
payload["notify_box_type"] = notify_box_type;
payload["question_type"] = question_type;
@@ -3498,7 +3557,6 @@ void LLIMMgr::inviteToSession(
LLIncomingCallDialog::processCallResponse(0, payload);
return;
}
-
if (voice_invite)
{
bool isRejectGroupCall = (gSavedSettings.getBOOL("VoiceCallsRejectGroup") && (notify_box_type == "VoiceInviteGroup"));
@@ -3537,6 +3595,9 @@ void LLIMMgr::inviteToSession(
if ( !mPendingInvitations.has(session_id.asString()) )
{
+ // we're throwing up a dialogue, so we're using the voice channel passed to us,
+ // save it in the payload.
+ payload["voice_channel_info"] = voice_channel_info;
if (caller_name.empty())
{
LLAvatarNameCache::get(caller_id,
@@ -3781,9 +3842,9 @@ void LLIMMgr::removeSessionObserver(LLIMSessionObserver *observer)
mSessionObservers.remove(observer);
}
-bool LLIMMgr::startCall(const LLUUID& session_id, LLVoiceChannel::EDirection direction)
+bool LLIMMgr::startCall(const LLUUID& session_id, LLVoiceChannel::EDirection direction, const LLSD& voice_channel_info)
{
- LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(session_id);
+ LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(session_id, voice_channel_info);
if (!voice_channel) return false;
voice_channel->setCallDirection(direction);
voice_channel->activate();
@@ -3792,7 +3853,7 @@ bool LLIMMgr::startCall(const LLUUID& session_id, LLVoiceChannel::EDirection dir
bool LLIMMgr::endCall(const LLUUID& session_id)
{
- LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(session_id);
+ LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(session_id, LLSD());
if (!voice_channel) return false;
voice_channel->deactivate();
@@ -4086,6 +4147,15 @@ public:
{
im_mgr->processSessionUpdate(input["body"]["info"]);
}
+ if (input["body"]["info"].has("voice_channel_info"))
+ {
+ LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(session_id);
+ if (session)
+ {
+ session->initVoiceChannel(input["body"]["info"]["voice_channel_info"]);
+ session->mVoiceChannel->activate();
+ }
+ }
}
};
@@ -4170,7 +4240,7 @@ public:
{
LLCoros::instance().launch("chatterBoxInvitationCoro",
boost::bind(&chatterBoxInvitationCoro, url,
- session_id, LLIMMgr::INVITATION_TYPE_INSTANT_MESSAGE));
+ session_id, LLIMMgr::INVITATION_TYPE_INSTANT_MESSAGE, LLSD()));
}
} //end if invitation has instant message
else if ( input["body"].has("voice") )
@@ -4182,7 +4252,7 @@ public:
}
BOOL session_type_p2p = input["body"]["voice"].get("invitation_type").asInteger() == EMultiAgentChatSessionType::P2P_CHAT_SESSION;
- LL_DEBUGS("Voice") << "Received P2P voice information from the server: " << input["body"]<< LL_ENDL;
+ LL_DEBUGS("Voice") << "Received voice information from the server: " << input["body"]<< LL_ENDL;
gIMMgr->inviteToSession(
input["body"]["session_id"].asUUID(),
input["body"]["session_name"].asString(),
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index 93a1a95b23..16444a6755 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -80,9 +80,11 @@ public:
} SType;
LLIMSession(const LLUUID& session_id, const std::string& name,
- const EInstantMessage& type, const LLUUID& other_participant_id, const uuid_vec_t& ids, const LLSD& voiceChannelInfo, bool has_offline_msg);
+ const EInstantMessage& type, const LLUUID& other_participant_id, const LLSD& voiceChannelInfo, const uuid_vec_t& ids, bool has_offline_msg);
virtual ~LLIMSession();
+ void initVoiceChannel(const LLSD &voiceChannelInfo = LLSD());
+
void sessionInitReplyReceived(const LLUUID& new_session_id);
void addMessagesFromHistoryCache(const std::list<LLSD>& history); // From local file
void addMessagesFromServerHistory(const LLSD& history, const std::string& target_from, const std::string& target_message, U32 timestamp); // From chat server
@@ -141,6 +143,7 @@ public:
LLVoiceChannel* mVoiceChannel;
LLIMSpeakerMgr* mSpeakers;
+ bool mP2PAsAdhocCall;
bool mSessionInitialized;
@@ -284,7 +287,7 @@ public:
* Get voice channel for the session specified by session_id
* Returns NULL if the session does not exist
*/
- LLVoiceChannel* getVoiceChannel(const LLUUID& session_id) const;
+ LLVoiceChannel* getVoiceChannel(const LLUUID& session_id, const LLSD& voice_channel_info = LLSD()) const;
/**
* Get im speaker manager for the session specified by session_id
@@ -464,7 +467,7 @@ public:
* Start call in a session
* @return false if voice channel doesn't exist
**/
- bool startCall(const LLUUID& session_id, LLVoiceChannel::EDirection direction = LLVoiceChannel::OUTGOING_CALL);
+ bool startCall(const LLUUID& session_id, LLVoiceChannel::EDirection direction = LLVoiceChannel::OUTGOING_CALL, const LLSD& voice_channel_info = LLSD());
/**
* End call in a session
diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp
index 60bada8f58..00691d4382 100644
--- a/indra/newview/llspeakers.cpp
+++ b/indra/newview/llspeakers.cpp
@@ -618,7 +618,7 @@ void LLSpeakerMgr::getSpeakerList(speaker_list_t* speaker_list, BOOL include_tex
const LLUUID LLSpeakerMgr::getSessionID()
{
- return mVoiceChannel->getSessionID();
+ return mVoiceChannel ? mVoiceChannel->getSessionID() : LLUUID();
}
bool LLSpeakerMgr::isSpeakerToBeRemoved(const LLUUID& speaker_id)
diff --git a/indra/newview/llspeakers.h b/indra/newview/llspeakers.h
index 22c9481687..aa594d1e13 100644
--- a/indra/newview/llspeakers.h
+++ b/indra/newview/llspeakers.h
@@ -241,6 +241,7 @@ public:
typedef std::vector<LLPointer<LLSpeaker> > speaker_list_t;
void getSpeakerList(speaker_list_t* speaker_list, BOOL include_text);
LLVoiceChannel* getVoiceChannel() { return mVoiceChannel; }
+ void setVoiceChannel(LLVoiceChannel *voiceChannel) { mVoiceChannel = voiceChannel; }
const LLUUID getSessionID();
bool isSpeakerToBeRemoved(const LLUUID& speaker_id);
diff --git a/indra/newview/llvoicechannel.cpp b/indra/newview/llvoicechannel.cpp
index f6658bbaab..f9d4a7e222 100644
--- a/indra/newview/llvoicechannel.cpp
+++ b/indra/newview/llvoicechannel.cpp
@@ -152,13 +152,16 @@ void LLVoiceChannel::handleStatusChange(EStatusType type)
case STATUS_LOGGED_IN:
break;
case STATUS_LEFT_CHANNEL:
- if (callStarted() && !mIgnoreNextSessionLeave && !sSuspended)
+ if (callStarted() && !sSuspended)
{
// if forceably removed from channel
// update the UI and revert to default channel
+ // deactivate will set the State to STATE_HUNG_UP
+ // so when handleStatusChange is called again during
+ // shutdown callStarted will return false and deactivate
+ // won't be called again.
deactivate();
}
- mIgnoreNextSessionLeave = FALSE;
break;
case STATUS_JOINING:
if (callStarted())
@@ -433,7 +436,7 @@ void LLVoiceChannelGroup::activate()
// Adding ad-hoc call participants to Recent People List.
// If it's an outgoing ad-hoc, we can use mInitialTargetIDs that holds IDs of people we
// called(both online and offline) as source to get people for recent (STORM-210).
- if (session->isOutgoingAdHoc())
+ if (session && session->isOutgoingAdHoc())
{
for (uuid_vec_t::iterator it = session->mInitialTargetIDs.begin(); it != session->mInitialTargetIDs.end(); ++it)
{
@@ -470,7 +473,7 @@ void LLVoiceChannelGroup::requestChannelInfo()
void LLVoiceChannelGroup::setChannelInfo(const LLSD& channelInfo)
{
- mChannelInfo = channelInfo;
+ mChannelInfo = channelInfo;
if (mState == STATE_NO_CHANNEL_INFO)
{
@@ -594,7 +597,14 @@ void LLVoiceChannelGroup::voiceCallCapCoro(std::string url)
postData["method"] = "call";
postData["session-id"] = mSessionID;
LLSD altParams;
- altParams["preferred_voice_server_type"] = gSavedSettings.getString("VoiceServerType");
+ std::string preferred_voice_server_type = gSavedSettings.getString("VoiceServerType");
+ if (preferred_voice_server_type.empty())
+ {
+ // default to the server type associated with the region we're on.
+ LLVoiceVersionInfo versionInfo = LLVoiceClient::getInstance()->getVersion();
+ preferred_voice_server_type = versionInfo.internalVoiceServerType;
+ }
+ altParams["preferred_voice_server_type"] = preferred_voice_server_type;
postData["alt_params"] = altParams;
LL_INFOS("Voice", "voiceCallCapCoro") << "Generic POST for " << url << LL_ENDL;
diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp
index 9dbf469ca8..6eadc3892e 100644
--- a/indra/newview/llvoiceclient.cpp
+++ b/indra/newview/llvoiceclient.cpp
@@ -538,12 +538,18 @@ LLVoiceP2PIncomingCallInterfacePtr LLVoiceClient::getIncomingCallInterface(const
// outgoing calls
LLVoiceP2POutgoingCallInterface *LLVoiceClient::getOutgoingCallInterface(const LLSD& voiceChannelInfo)
{
- std::string voiceServerType = gSavedSettings.getString("VoiceServerType");
+ std::string voice_server_type = gSavedSettings.getString("VoiceServerType");
+ if (voice_server_type.empty())
+ {
+ // default to the server type associated with the region we're on.
+ LLVoiceVersionInfo versionInfo = LLVoiceClient::getInstance()->getVersion();
+ voice_server_type = versionInfo.internalVoiceServerType;
+ }
if (voiceChannelInfo.has("voice_server_type"))
{
- voiceServerType = voiceChannelInfo["voice_server_type"].asString();
+ voice_server_type = voiceChannelInfo["voice_server_type"].asString();
}
- LLVoiceModuleInterface *module = getVoiceModule(voiceServerType);
+ LLVoiceModuleInterface *module = getVoiceModule(voice_server_type);
return dynamic_cast<LLVoiceP2POutgoingCallInterface *>(module);
}
diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h
index 3b1b3bd0c4..6b6cb452ee 100644
--- a/indra/newview/llvoiceclient.h
+++ b/indra/newview/llvoiceclient.h
@@ -421,7 +421,7 @@ public:
// initiate a call with a peer using the P2P interface, which only applies to some
// voice server types. Otherwise, a group call should be used for P2P
- LLVoiceP2POutgoingCallInterface* getOutgoingCallInterface(const LLSD& voiceChannelInfo);
+ LLVoiceP2POutgoingCallInterface* getOutgoingCallInterface(const LLSD& voiceChannelInfo = LLSD());
LLVoiceP2PIncomingCallInterfacePtr getIncomingCallInterface(const LLSD &voiceCallInfo);
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index be9e055203..ccdd86dd87 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -1200,7 +1200,7 @@ bool LLVivoxVoiceClient::provisionVoiceAccount()
LL_WARNS("Voice") << "Could not access voice provision cap after " << retryCount << " attempts." << LL_ENDL;
return false;
}
- LL_WARNS("Voice") << "Voice Provision Result." << result << LL_ENDL;
+ LL_DEBUGS("Voice") << "Voice Provision Result." << result << LL_ENDL;
std::string voiceSipUriHostname;
std::string voiceAccountServerUri;
std::string voiceUserName = result["username"].asString();
@@ -1749,7 +1749,7 @@ bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession)
}
else if ((message == "failed") || (message == "removed") || (message == "timeout"))
{ // we will get a removed message if a voice call is declined.
-
+ LL_INFOS("Voice") << "Result:" << result << LL_ENDL;
if (message == "failed")
{
int reason = result["reason"].asInteger();
@@ -4952,6 +4952,7 @@ bool LLVivoxVoiceClient::setSpatialChannel(const LLSD& channelInfo)
void LLVivoxVoiceClient::callUser(const LLUUID &uuid)
{
std::string userURI = sipURIFromID(uuid);
+ mProcessChannels = true;
switchChannel(userURI, false, true, true);
}
@@ -4974,7 +4975,7 @@ bool LLVivoxVoiceClient::answerInvite(const std::string &sessionHandle)
session->mIsSpatial = false;
session->mReconnect = false;
session->mIsP2P = true;
-
+ mProcessChannels = true;
joinSession(session);
return true;
}
@@ -5078,7 +5079,9 @@ void LLVivoxVoiceClient::leaveNonSpatialChannel()
void LLVivoxVoiceClient::processChannels(bool process)
{
- mProcessChannels = process;
+ mCurrentParcelLocalID = -1;
+ mCurrentRegionName.clear();
+ mProcessChannels = process;
}
bool LLVivoxVoiceClient::isCurrentChannel(const LLSD &channelInfo)
@@ -5456,6 +5459,8 @@ void LLVivoxVoiceClient::setVoiceEnabled(bool enabled)
LLVoiceChannel::getCurrentVoiceChannel()->deactivate();
gAgent.setVoiceConnected(false);
status = LLVoiceClientStatusObserver::STATUS_VOICE_DISABLED;
+ mCurrentParcelLocalID = -1;
+ mCurrentRegionName.clear();
}
notifyStatusObservers(status);
@@ -6339,8 +6344,7 @@ void LLVivoxVoiceClient::predAvatarNameResolution(const LLVivoxVoiceClient::sess
session->mCallerID,
session->mName,
IM_SESSION_P2P_INVITE,
- LLIMMgr::INVITATION_TYPE_VOICE,
- session->getVoiceChannelInfo());
+ LLIMMgr::INVITATION_TYPE_VOICE);
}
}
}
diff --git a/indra/newview/llvoicewebrtc.cpp b/indra/newview/llvoicewebrtc.cpp
index 710067c2bf..ddbe2eb552 100644
--- a/indra/newview/llvoicewebrtc.cpp
+++ b/indra/newview/llvoicewebrtc.cpp
@@ -87,7 +87,7 @@ namespace {
const F32 VOLUME_SCALE_WEBRTC = 0.01f;
const F32 LEVEL_SCALE_WEBRTC = 0.008f;
- const F32 SPEAKING_AUDIO_LEVEL = 0.40;
+ const F32 SPEAKING_AUDIO_LEVEL = 0.35;
static const std::string REPORTED_VOICE_SERVER_TYPE = "Secondlife WebRTC Gateway";
@@ -254,6 +254,7 @@ void LLWebRTCVoiceClient::init(LLPumpIO* pump)
mWebRTCDeviceInterface = llwebrtc::getDeviceInterface();
mWebRTCDeviceInterface->setDevicesObserver(this);
+ mMainQueue = LL::WorkQueue::getInstance("mainloop");
}
void LLWebRTCVoiceClient::terminate()
@@ -552,6 +553,7 @@ void LLWebRTCVoiceClient::updateNeighboringRegions()
// Estate voice requires connection to neighboring regions.
mNeighboringRegions.clear();
+ // add current region.
mNeighboringRegions.insert(gAgent.getRegion()->getRegionID());
// base off of speaker position as it'll move more slowly than camera position.
@@ -809,9 +811,12 @@ void LLWebRTCVoiceClient::OnConnectionEstablished(const std::string &channelID,
}
mSession = mNextSession;
mNextSession.reset();
+ }
+ if (mSession)
+ {
// Add ourselves as a participant.
- mSession->addParticipant(gAgentID);
+ mSession->addParticipant(gAgentID, gAgent.getRegion()->getRegionID());
}
// The current session was established.
@@ -832,14 +837,19 @@ void LLWebRTCVoiceClient::OnConnectionEstablished(const std::string &channelID,
void LLWebRTCVoiceClient::OnConnectionShutDown(const std::string &channelID, const LLUUID &regionID)
{
- if (gAgent.getRegion()->getRegionID() == regionID)
+ if (mSession && (mSession->mChannelID == channelID))
{
- if (mSession && mSession->mChannelID == channelID)
+ if (gAgent.getRegion()->getRegionID() == regionID)
{
- LL_DEBUGS("Voice") << "Main WebRTC Connection Shut Down." << LL_ENDL;
+ if (mSession && mSession->mChannelID == channelID)
+ {
+ LL_DEBUGS("Voice") << "Main WebRTC Connection Shut Down." << LL_ENDL;
+ }
}
+ mSession->removeAllParticipants(regionID);
}
}
+
void LLWebRTCVoiceClient::OnConnectionFailure(const std::string &channelID,
const LLUUID &regionID,
LLVoiceClientStatusObserver::EStatusType status_type)
@@ -915,6 +925,13 @@ void LLWebRTCVoiceClient::updatePosition(void)
enforceTether();
updateNeighboringRegions();
+
+ // update own region id to be the region id avatar is currently in.
+ LLWebRTCVoiceClient::participantStatePtr_t participant = findParticipantByID("Estate", gAgentID);
+ if(participant)
+ {
+ participant->mRegion = gAgent.getRegion()->getRegionID();
+ }
}
}
@@ -1091,13 +1108,13 @@ LLWebRTCVoiceClient::participantStatePtr_t LLWebRTCVoiceClient::findParticipantB
return result;
}
-LLWebRTCVoiceClient::participantStatePtr_t LLWebRTCVoiceClient::addParticipantByID(const std::string &channelID, const LLUUID &id)
+LLWebRTCVoiceClient::participantStatePtr_t LLWebRTCVoiceClient::addParticipantByID(const std::string &channelID, const LLUUID &id, const LLUUID& region)
{
participantStatePtr_t result;
LLWebRTCVoiceClient::sessionState::ptr_t session = sessionState::matchSessionByChannelID(channelID);
if (session)
{
- result = session->addParticipant(id);
+ result = session->addParticipant(id, region);
if (session->mNotifyOnFirstJoin && (id != gAgentID))
{
notifyStatusObservers(LLVoiceClientStatusObserver::STATUS_JOINED);
@@ -1106,7 +1123,7 @@ LLWebRTCVoiceClient::participantStatePtr_t LLWebRTCVoiceClient::addParticipantBy
return result;
}
-void LLWebRTCVoiceClient::removeParticipantByID(const std::string &channelID, const LLUUID &id)
+void LLWebRTCVoiceClient::removeParticipantByID(const std::string &channelID, const LLUUID &id, const LLUUID& region)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE
@@ -1115,30 +1132,27 @@ void LLWebRTCVoiceClient::removeParticipantByID(const std::string &channelID, co
if (session)
{
participantStatePtr_t participant = session->findParticipantByID(id);
- if (participant)
+ if (participant && (participant->mRegion == region))
{
session->removeParticipant(participant);
- if (session->mHangupOnLastLeave && (id != gAgentID) && (session->mParticipantsByUUID.size() <= 1))
- {
- notifyStatusObservers(LLVoiceClientStatusObserver::STATUS_LEFT_CHANNEL);
- }
}
}
}
// participantState level participant management
-LLWebRTCVoiceClient::participantState::participantState(const LLUUID& agent_id) :
+LLWebRTCVoiceClient::participantState::participantState(const LLUUID& agent_id, const LLUUID& region) :
mURI(agent_id.asString()),
mAvatarID(agent_id),
mIsSpeaking(false),
mIsModeratorMuted(false),
mLevel(0.f),
- mVolume(LLVoiceClient::VOLUME_DEFAULT)
+ mVolume(LLVoiceClient::VOLUME_DEFAULT),
+ mRegion(region)
{
}
-LLWebRTCVoiceClient::participantStatePtr_t LLWebRTCVoiceClient::sessionState::addParticipant(const LLUUID& agent_id)
+LLWebRTCVoiceClient::participantStatePtr_t LLWebRTCVoiceClient::sessionState::addParticipant(const LLUUID& agent_id, const LLUUID& region)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE
@@ -1150,26 +1164,27 @@ LLWebRTCVoiceClient::participantStatePtr_t LLWebRTCVoiceClient::sessionState::ad
if (iter != mParticipantsByUUID.end())
{
result = iter->second;
+ result->mRegion = region;
}
- if(!result)
+ if (!result)
{
// participant isn't already in one list or the other.
- result.reset(new participantState(agent_id));
+ result.reset(new participantState(agent_id, region));
mParticipantsByUUID.insert(participantUUIDMap::value_type(agent_id, result));
- result->mAvatarID = agent_id;
-
- LLWebRTCVoiceClient::getInstance()->lookupName(agent_id);
+ result->mAvatarID = agent_id;
+ }
- LLSpeakerVolumeStorage::getInstance()->getSpeakerVolume(result->mAvatarID, result->mVolume);
- if (!LLWebRTCVoiceClient::sShuttingDown)
- {
- LLWebRTCVoiceClient::getInstance()->notifyParticipantObservers();
- }
+ LLWebRTCVoiceClient::getInstance()->lookupName(agent_id);
- LL_DEBUGS("Voice") << "Participant \"" << result->mURI << "\" added." << LL_ENDL;
+ LLSpeakerVolumeStorage::getInstance()->getSpeakerVolume(result->mAvatarID, result->mVolume);
+ if (!LLWebRTCVoiceClient::sShuttingDown)
+ {
+ LLWebRTCVoiceClient::getInstance()->notifyParticipantObservers();
}
+ LL_DEBUGS("Voice") << "Participant \"" << result->mURI << "\" added." << LL_ENDL;
+
return result;
}
@@ -1197,13 +1212,14 @@ void LLWebRTCVoiceClient::sessionState::removeParticipant(const LLWebRTCVoiceCli
if (participant)
{
+ LLUUID participantID = participant->mAvatarID;
participantUUIDMap::iterator iter = mParticipantsByUUID.find(participant->mAvatarID);
- LL_DEBUGS("Voice") << "participant \"" << participant->mURI << "\" (" << participant->mAvatarID << ") removed." << LL_ENDL;
+ LL_DEBUGS("Voice") << "participant \"" << participant->mURI << "\" (" << participantID << ") removed." << LL_ENDL;
if (iter == mParticipantsByUUID.end())
{
- LL_WARNS("Voice") << "Internal error: participant ID " << participant->mAvatarID << " not in UUID map" << LL_ENDL;
+ LL_WARNS("Voice") << "Internal error: participant ID " << participantID << " not in UUID map" << LL_ENDL;
}
else
{
@@ -1213,16 +1229,27 @@ void LLWebRTCVoiceClient::sessionState::removeParticipant(const LLWebRTCVoiceCli
LLWebRTCVoiceClient::getInstance()->notifyParticipantObservers();
}
}
+ if (mHangupOnLastLeave && (participantID != gAgentID) && (mParticipantsByUUID.size() <= 1))
+ {
+ LLWebRTCVoiceClient::getInstance()->notifyStatusObservers(LLVoiceClientStatusObserver::STATUS_LEFT_CHANNEL);
+ }
}
}
-void LLWebRTCVoiceClient::sessionState::removeAllParticipants()
+void LLWebRTCVoiceClient::sessionState::removeAllParticipants(const LLUUID &region)
{
- LL_DEBUGS("Voice") << "called" << LL_ENDL;
+ std::vector<participantStatePtr_t> participantsToRemove;
- while (!mParticipantsByUUID.empty())
+ for (auto& participantEntry : mParticipantsByUUID)
+ {
+ if (region.isNull() || (participantEntry.second->mRegion == region))
+ {
+ participantsToRemove.push_back(participantEntry.second);
+ }
+ }
+ for (auto& participant : participantsToRemove)
{
- removeParticipant(mParticipantsByUUID.begin()->second);
+ removeParticipant(participant);
}
}
@@ -1269,6 +1296,35 @@ BOOL LLWebRTCVoiceClient::isSessionCallBackPossible(const LLUUID &session_id)
}
// Channel Management
+
+bool LLWebRTCVoiceClient::setSpatialChannel(const LLSD &channelInfo)
+{
+ LL_INFOS("Voice") << "SetSpatialChannel " << channelInfo << LL_ENDL;
+ LLViewerRegion *regionp = gAgent.getRegion();
+ if (!regionp)
+ {
+ return false;
+ }
+ LLParcel *parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+
+ // we don't really have credentials for a spatial channel in webrtc,
+ // it's all handled by the sim.
+ if (channelInfo.isMap() && channelInfo.has("channel_uri"))
+ {
+ bool allow_voice = !channelInfo["channel_uri"].asString().empty();
+ if (parcel)
+ {
+ parcel->setParcelFlag(PF_ALLOW_VOICE_CHAT, allow_voice);
+ parcel->setParcelFlag(PF_USE_ESTATE_VOICE_CHAN, channelInfo["channel_uri"].asUUID() == regionp->getRegionID());
+ }
+ else
+ {
+ regionp->setRegionFlag(REGION_FLAGS_ALLOW_VOICE, allow_voice);
+ }
+ }
+ return true;
+}
+
void LLWebRTCVoiceClient::leaveNonSpatialChannel()
{
LL_DEBUGS("Voice") << "Request to leave non-spatial channel." << LL_ENDL;
@@ -1457,7 +1513,6 @@ void LLWebRTCVoiceClient::setVoiceEnabled(bool enabled)
updatePosition();
if (!mIsCoroutineActive)
{
- mMainQueue = LL::WorkQueue::getInstance("mainloop");
LLCoros::instance().launch("LLWebRTCVoiceClient::voiceConnectionCoro",
boost::bind(&LLWebRTCVoiceClient::voiceConnectionCoro, LLWebRTCVoiceClient::getInstance()));
}
@@ -2116,7 +2171,7 @@ void LLVoiceWebRTCConnection::OnIceCandidate(const llwebrtc::LLWebRTCIceCandidat
void LLVoiceWebRTCConnection::processIceUpdates()
{
mOutstandingRequests++;
- LLCoros::getInstance()->launch("LLVoiceWebRTCConnection::requestVoiceConnectionCoro",
+ LLCoros::getInstance()->launch("LLVoiceWebRTCConnection::processIceUpdatesCoro",
boost::bind(&LLVoiceWebRTCConnection::processIceUpdatesCoro, this));
}
@@ -2192,6 +2247,7 @@ void LLVoiceWebRTCConnection::processIceUpdatesCoro()
if (LLWebRTCVoiceClient::isShuttingDown())
{
+ mOutstandingRequests--;
return;
}
@@ -2281,6 +2337,7 @@ void LLVoiceWebRTCConnection::OnRenegotiationNeeded()
{
setVoiceConnectionState(VOICE_STATE_SESSION_RETRY);
}
+ mCurrentStatus = LLVoiceClientStatusObserver::ERROR_UNKNOWN;
});
}
@@ -2369,6 +2426,7 @@ void LLVoiceWebRTCConnection::breakVoiceConnectionCoro()
{
LL_DEBUGS("Voice") << "no capabilities for voice provisioning; waiting " << LL_ENDL;
setVoiceConnectionState(VOICE_STATE_SESSION_RETRY);
+ mOutstandingRequests--;
return;
}
@@ -2376,6 +2434,7 @@ void LLVoiceWebRTCConnection::breakVoiceConnectionCoro()
if (url.empty())
{
setVoiceConnectionState(VOICE_STATE_SESSION_RETRY);
+ mOutstandingRequests--;
return;
}
@@ -2405,6 +2464,7 @@ void LLVoiceWebRTCConnection::breakVoiceConnectionCoro()
if (LLWebRTCVoiceClient::isShuttingDown())
{
+ mOutstandingRequests--;
return;
}
@@ -2431,7 +2491,9 @@ void LLVoiceWebRTCSpatialConnection::requestVoiceConnection()
if (!regionp || !regionp->capabilitiesReceived())
{
LL_DEBUGS("Voice") << "no capabilities for voice provisioning; waiting " << LL_ENDL;
- setVoiceConnectionState(VOICE_STATE_SESSION_RETRY);
+
+ // try again.
+ setVoiceConnectionState(VOICE_STATE_REQUEST_CONNECTION);
return;
}
@@ -2634,7 +2696,11 @@ bool LLVoiceWebRTCConnection::connectionStateMachine()
{
sendJoin(); // tell the Secondlife WebRTC server that we're here via the data channel.
setVoiceConnectionState(VOICE_STATE_SESSION_UP);
- LLWebRTCVoiceClient::getInstance()->sendPositionUpdate(true);
+ if (isSpatial())
+ {
+ LLWebRTCVoiceClient::getInstance()->updatePosition();
+ LLWebRTCVoiceClient::getInstance()->sendPositionUpdate(true);
+ }
}
break;
}
@@ -2799,7 +2865,7 @@ void LLVoiceWebRTCConnection::OnDataReceivedImpl(const std::string &data, bool b
new_participant |= joined;
if (!participant && joined && (primary || !isSpatial()))
{
- participant = LLWebRTCVoiceClient::getInstance()->addParticipantByID(mChannelID, agent_id);
+ participant = LLWebRTCVoiceClient::getInstance()->addParticipantByID(mChannelID, agent_id, mRegionID);
}
if (participant)
@@ -2809,7 +2875,7 @@ void LLVoiceWebRTCConnection::OnDataReceivedImpl(const std::string &data, bool b
// an existing participant is leaving.
if (agent_id != gAgentID)
{
- LLWebRTCVoiceClient::getInstance()->removeParticipantByID(mChannelID, agent_id);
+ LLWebRTCVoiceClient::getInstance()->removeParticipantByID(mChannelID, agent_id, mRegionID);
}
}
else
@@ -2983,8 +3049,9 @@ void LLVoiceWebRTCAdHocConnection::requestVoiceConnection()
LL_DEBUGS("Voice") << "Requesting voice connection." << LL_ENDL;
if (!regionp || !regionp->capabilitiesReceived())
{
- LL_DEBUGS("Voice") << "no capabilities for voice provisioning; waiting " << LL_ENDL;
- setVoiceConnectionState(VOICE_STATE_SESSION_RETRY);
+ LL_DEBUGS("Voice") << "no capabilities for voice provisioning; retrying " << LL_ENDL;
+ // try again.
+ setVoiceConnectionState(VOICE_STATE_REQUEST_CONNECTION);
return;
}
diff --git a/indra/newview/llvoicewebrtc.h b/indra/newview/llvoicewebrtc.h
index aa3298ec1b..c417dfe329 100644
--- a/indra/newview/llvoicewebrtc.h
+++ b/indra/newview/llvoicewebrtc.h
@@ -144,12 +144,7 @@ public:
startAdHocSession(channelInfo, notify_on_first_join, hangup_on_last_leave);
}
- bool setSpatialChannel(const LLSD &channelInfo) override
- {
- // we don't really have credentials for a spatial channel in webrtc,
- // it's all handled by the sim.
- return true;
- }
+ bool setSpatialChannel(const LLSD &channelInfo) override;
void leaveNonSpatialChannel() override;
@@ -206,7 +201,8 @@ public:
void OnConnectionFailure(const std::string &channelID,
const LLUUID &regionID,
LLVoiceClientStatusObserver::EStatusType status_type = LLVoiceClientStatusObserver::ERROR_UNKNOWN);
- void sendPositionUpdate(bool force);
+ void updatePosition(void); // update the internal position state
+ void sendPositionUpdate(bool force); // send the position to the voice server.
void updateOwnVolume();
//////////////////////////////
@@ -233,7 +229,7 @@ public:
struct participantState
{
public:
- participantState(const LLUUID& agent_id);
+ participantState(const LLUUID& agent_id, const LLUUID& region);
bool isAvatar();
@@ -245,12 +241,13 @@ public:
F32 mVolume; // the gain applied to the participant
bool mIsSpeaking;
bool mIsModeratorMuted;
+ LLUUID mRegion;
};
typedef boost::shared_ptr<participantState> participantStatePtr_t;
participantStatePtr_t findParticipantByID(const std::string &channelID, const LLUUID &id);
- participantStatePtr_t addParticipantByID(const std::string& channelID, const LLUUID &id);
- void removeParticipantByID(const std::string& channelID, const LLUUID &id);
+ participantStatePtr_t addParticipantByID(const std::string& channelID, const LLUUID &id, const LLUUID& region);
+ void removeParticipantByID(const std::string& channelID, const LLUUID &id, const LLUUID& region);
protected:
@@ -267,9 +264,9 @@ public:
static void addSession(const std::string &channelID, ptr_t& session);
virtual ~sessionState();
- participantStatePtr_t addParticipant(const LLUUID& agent_id);
+ participantStatePtr_t addParticipant(const LLUUID& agent_id, const LLUUID& region);
void removeParticipant(const participantStatePtr_t &participant);
- void removeAllParticipants();
+ void removeAllParticipants(const LLUUID& region = LLUUID());
participantStatePtr_t findParticipantByID(const LLUUID& id);
@@ -402,7 +399,6 @@ public:
/////////////////////////////
// Sending updates of current state
- void updatePosition(void);
void setListenerPosition(const LLVector3d &position, const LLVector3 &velocity, const LLQuaternion &rot);
void setAvatarPosition(const LLVector3d &position, const LLVector3 &velocity, const LLQuaternion &rot);
diff --git a/indra/newview/skins/default/xui/en/floater_incoming_call.xml b/indra/newview/skins/default/xui/en/floater_incoming_call.xml
index a7864381a9..e576310160 100644
--- a/indra/newview/skins/default/xui/en/floater_incoming_call.xml
+++ b/indra/newview/skins/default/xui/en/floater_incoming_call.xml
@@ -12,7 +12,7 @@
width="550">
<floater.string
name="lifetime">
- 5
+ 30
</floater.string>
<floater.string
name="localchat">