diff options
-rw-r--r-- | autobuild.xml | 12 | ||||
-rw-r--r-- | indra/llwebrtc/llwebrtc.cpp | 22 | ||||
-rw-r--r-- | indra/llwebrtc/llwebrtc_impl.h | 2 | ||||
-rw-r--r-- | indra/newview/app_settings/settings.xml | 4 | ||||
-rw-r--r-- | indra/newview/llimview.cpp | 180 | ||||
-rw-r--r-- | indra/newview/llimview.h | 9 | ||||
-rw-r--r-- | indra/newview/llspeakers.cpp | 2 | ||||
-rw-r--r-- | indra/newview/llspeakers.h | 1 | ||||
-rw-r--r-- | indra/newview/llvoicechannel.cpp | 20 | ||||
-rw-r--r-- | indra/newview/llvoiceclient.cpp | 12 | ||||
-rw-r--r-- | indra/newview/llvoiceclient.h | 2 | ||||
-rw-r--r-- | indra/newview/llvoicevivox.cpp | 16 | ||||
-rw-r--r-- | indra/newview/llvoicewebrtc.cpp | 149 | ||||
-rw-r--r-- | indra/newview/llvoicewebrtc.h | 22 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/floater_incoming_call.xml | 2 |
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 ®ionID) { - 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 ®ionID, 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 ®ion) { - 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 ®ionID, 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"> |