Merge branch 'webrtc-voice' of https://github.com/secondlife/viewer
# Conflicts: # indra/newview/app_settings/settings.xmlmaster
commit
5e5edd78ed
|
|
@ -3256,11 +3256,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>a49fb3bb8aaf8325e7c6c4b6036db3da16afa2c9</string>
|
||||
<string>21e31d2c2fffdb59d8f50b80db079f86f2df2483</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>md5</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>
|
||||
|
|
@ -3270,11 +3270,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>
|
||||
|
|
@ -3284,11 +3284,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<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>
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -276,7 +276,7 @@ class LLWebRTCPeerConnectionImpl : public LLWebRTCPeerConnectionInterface,
|
|||
{
|
||||
public:
|
||||
LLWebRTCPeerConnectionImpl();
|
||||
~LLWebRTCPeerConnectionImpl() {}
|
||||
~LLWebRTCPeerConnectionImpl();
|
||||
|
||||
void init(LLWebRTCImpl * webrtc_impl);
|
||||
void terminate();
|
||||
|
|
|
|||
|
|
@ -18659,13 +18659,13 @@ Change of this parameter will affect the layout of buttons in notification toast
|
|||
<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>
|
||||
|
|
|
|||
|
|
@ -125,7 +125,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);
|
||||
|
||||
|
|
@ -560,7 +560,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);
|
||||
|
|
@ -602,7 +609,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);
|
||||
|
|
@ -623,7 +637,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
|
||||
|
|
@ -689,7 +703,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
|
||||
|
|
@ -839,8 +853,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),
|
||||
|
|
@ -855,56 +869,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.
|
||||
|
||||
|
|
@ -914,7 +902,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
|
||||
|
|
@ -944,6 +932,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();
|
||||
|
|
@ -1047,7 +1097,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);
|
||||
}
|
||||
|
|
@ -1079,7 +1129,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1685,7 +1738,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
|
||||
|
|
@ -2000,7 +2053,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)
|
||||
|
|
@ -2008,6 +2061,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;
|
||||
}
|
||||
|
|
@ -2416,7 +2477,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)
|
||||
|
|
@ -3040,7 +3101,7 @@ void LLIncomingCallDialog::onLifetimeExpired()
|
|||
LLUUID session_id = mPayload["session_id"].asUUID();
|
||||
gIMMgr->clearPendingAgentListUpdates(session_id);
|
||||
gIMMgr->clearPendingInvitation(session_id);
|
||||
closeFloater();
|
||||
LLIncomingCallDialog::onReject(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3232,7 +3293,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
|
||||
{
|
||||
|
|
@ -3286,8 +3347,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")
|
||||
|
|
@ -3984,7 +4044,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;
|
||||
|
||||
|
|
@ -4014,7 +4073,6 @@ void LLIMMgr::inviteToSession(
|
|||
LLIncomingCallDialog::processCallResponse(0, payload);
|
||||
return;
|
||||
}
|
||||
|
||||
if (voice_invite)
|
||||
{
|
||||
bool isRejectGroupCall = (gSavedSettings.getBOOL("VoiceCallsRejectGroup") && (notify_box_type == "VoiceInviteGroup"));
|
||||
|
|
@ -4061,6 +4119,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,
|
||||
|
|
@ -4346,9 +4407,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();
|
||||
|
|
@ -4357,7 +4418,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();
|
||||
|
|
@ -4812,6 +4873,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();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -4973,7 +5043,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") )
|
||||
|
|
@ -4985,7 +5055,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(),
|
||||
|
|
|
|||
|
|
@ -89,9 +89,11 @@ public:
|
|||
// [/SL:KB]
|
||||
|
||||
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
|
||||
|
|
@ -158,6 +160,7 @@ public:
|
|||
|
||||
LLVoiceChannel* mVoiceChannel;
|
||||
LLIMSpeakerMgr* mSpeakers;
|
||||
bool mP2PAsAdhocCall;
|
||||
|
||||
bool mSessionInitialized;
|
||||
|
||||
|
|
@ -326,7 +329,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
|
||||
|
|
@ -518,7 +521,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
|
||||
|
|
|
|||
|
|
@ -624,7 +624,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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -551,12 +551,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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -442,7 +442,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);
|
||||
|
||||
|
|
|
|||
|
|
@ -1319,7 +1319,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();
|
||||
|
|
@ -1868,7 +1868,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();
|
||||
|
|
@ -5113,6 +5113,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);
|
||||
}
|
||||
|
|
@ -5135,7 +5136,7 @@ bool LLVivoxVoiceClient::answerInvite(const std::string &sessionHandle)
|
|||
session->mIsSpatial = false;
|
||||
session->mReconnect = false;
|
||||
session->mIsP2P = true;
|
||||
|
||||
mProcessChannels = true;
|
||||
joinSession(session);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -5239,7 +5240,9 @@ void LLVivoxVoiceClient::leaveNonSpatialChannel()
|
|||
|
||||
void LLVivoxVoiceClient::processChannels(bool process)
|
||||
{
|
||||
mProcessChannels = process;
|
||||
mCurrentParcelLocalID = -1;
|
||||
mCurrentRegionName.clear();
|
||||
mProcessChannels = process;
|
||||
}
|
||||
|
||||
bool LLVivoxVoiceClient::isCurrentChannel(const LLSD &channelInfo)
|
||||
|
|
@ -5617,6 +5620,8 @@ void LLVivoxVoiceClient::setVoiceEnabled(bool enabled)
|
|||
LLVoiceChannel::getCurrentVoiceChannel()->deactivate();
|
||||
gAgent.setVoiceConnected(false);
|
||||
status = LLVoiceClientStatusObserver::STATUS_VOICE_DISABLED;
|
||||
mCurrentParcelLocalID = -1;
|
||||
mCurrentRegionName.clear();
|
||||
}
|
||||
|
||||
notifyStatusObservers(status);
|
||||
|
|
@ -6503,8 +6508,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
LLSpeakerVolumeStorage::getInstance()->getSpeakerVolume(result->mAvatarID, result->mVolume);
|
||||
if (!LLWebRTCVoiceClient::sShuttingDown)
|
||||
{
|
||||
LLWebRTCVoiceClient::getInstance()->notifyParticipantObservers();
|
||||
}
|
||||
|
||||
LL_DEBUGS("Voice") << "Participant \"" << result->mURI << "\" added." << LL_ENDL;
|
||||
result->mAvatarID = agent_id;
|
||||
}
|
||||
|
||||
LLWebRTCVoiceClient::getInstance()->lookupName(agent_id);
|
||||
|
||||
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)
|
||||
{
|
||||
removeParticipant(mParticipantsByUUID.begin()->second);
|
||||
if (region.isNull() || (participantEntry.second->mRegion == region))
|
||||
{
|
||||
participantsToRemove.push_back(participantEntry.second);
|
||||
}
|
||||
}
|
||||
for (auto& participant : participantsToRemove)
|
||||
{
|
||||
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;
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -2371,6 +2428,7 @@ void LLVoiceWebRTCConnection::breakVoiceConnectionCoro()
|
|||
{
|
||||
LL_DEBUGS("Voice") << "no capabilities for voice provisioning; waiting " << LL_ENDL;
|
||||
setVoiceConnectionState(VOICE_STATE_SESSION_RETRY);
|
||||
mOutstandingRequests--;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -2378,6 +2436,7 @@ void LLVoiceWebRTCConnection::breakVoiceConnectionCoro()
|
|||
if (url.empty())
|
||||
{
|
||||
setVoiceConnectionState(VOICE_STATE_SESSION_RETRY);
|
||||
mOutstandingRequests--;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -2407,6 +2466,7 @@ void LLVoiceWebRTCConnection::breakVoiceConnectionCoro()
|
|||
|
||||
if (LLWebRTCVoiceClient::isShuttingDown())
|
||||
{
|
||||
mOutstandingRequests--;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -2433,7 +2493,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;
|
||||
}
|
||||
|
||||
|
|
@ -2636,7 +2698,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;
|
||||
}
|
||||
|
|
@ -2801,7 +2867,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)
|
||||
|
|
@ -2811,7 +2877,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
|
||||
|
|
@ -2985,8 +3051,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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
width="550">
|
||||
<floater.string
|
||||
name="lifetime">
|
||||
5
|
||||
30
|
||||
</floater.string>
|
||||
<floater.string
|
||||
name="localchat">
|
||||
|
|
|
|||
Loading…
Reference in New Issue