summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/llwebrtc/llwebrtc.cpp51
-rw-r--r--indra/llwebrtc/llwebrtc.h3
-rw-r--r--indra/llwebrtc/llwebrtc_impl.h2
-rw-r--r--indra/newview/llfloaterimsession.cpp11
-rw-r--r--indra/newview/llfloaterimsession.h5
-rw-r--r--indra/newview/llimview.cpp37
-rw-r--r--indra/newview/llimview.h2
-rw-r--r--indra/newview/llvoicechannel.h4
-rw-r--r--indra/newview/llvoiceclient.cpp7
-rw-r--r--indra/newview/llvoicevivox.cpp3
-rw-r--r--indra/newview/llvoicewebrtc.cpp27
-rw-r--r--indra/newview/llvoicewebrtc.h7
12 files changed, 107 insertions, 52 deletions
diff --git a/indra/llwebrtc/llwebrtc.cpp b/indra/llwebrtc/llwebrtc.cpp
index 97c04ae446..14fb63ec2a 100644
--- a/indra/llwebrtc/llwebrtc.cpp
+++ b/indra/llwebrtc/llwebrtc.cpp
@@ -280,9 +280,15 @@ void LLWebRTCImpl::terminate()
{
connection->terminate();
}
- mPeerConnections.clear();
+
+ // connection->terminate() above spawns a number of Signaling thread calls to
+ // shut down the connection. The following Blocking Call will wait
+ // until they're done before it's executed, allowing time to clean up.
mSignalingThread->BlockingCall([this]() { mPeerConnectionFactory = nullptr; });
+
+ mPeerConnections.clear();
+
mWorkerThread->BlockingCall(
[this]()
{
@@ -627,7 +633,6 @@ void LLWebRTCImpl::freePeerConnection(LLWebRTCPeerConnectionInterface* peer_conn
std::find(mPeerConnections.begin(), mPeerConnections.end(), peer_connection);
if (it != mPeerConnections.end())
{
- (*it)->terminate();
mPeerConnections.erase(it);
}
if (mPeerConnections.empty())
@@ -645,7 +650,6 @@ void LLWebRTCImpl::freePeerConnection(LLWebRTCPeerConnectionInterface* peer_conn
LLWebRTCPeerConnectionImpl::LLWebRTCPeerConnectionImpl() :
mWebRTCImpl(nullptr),
- mClosing(false),
mPeerConnection(nullptr),
mMute(false),
mAnswerReceived(false)
@@ -654,7 +658,6 @@ LLWebRTCPeerConnectionImpl::LLWebRTCPeerConnectionImpl() :
LLWebRTCPeerConnectionImpl::~LLWebRTCPeerConnectionImpl()
{
- terminate();
mSignalingObserverList.clear();
mDataObserverList.clear();
}
@@ -670,24 +673,35 @@ void LLWebRTCPeerConnectionImpl::init(LLWebRTCImpl * webrtc_impl)
}
void LLWebRTCPeerConnectionImpl::terminate()
{
- rtc::scoped_refptr<webrtc::PeerConnectionInterface> connection;
- mPeerConnection.swap(connection);
- rtc::scoped_refptr<webrtc::DataChannelInterface> dataChannel;
- mDataChannel.swap(dataChannel);
- rtc::scoped_refptr<webrtc::MediaStreamInterface> localStream;
- mLocalStream.swap(localStream);
-
mWebRTCImpl->PostSignalingTask(
[=]()
{
- if (connection)
- {
- connection->Close();
- }
- if (dataChannel)
+ if (mPeerConnection)
{
- dataChannel->UnregisterObserver();
- dataChannel->Close();
+ if (mDataChannel)
+ {
+ {
+ mDataChannel->Close();
+ mDataChannel = nullptr;
+ }
+ }
+
+ mPeerConnection->Close();
+ if (mLocalStream)
+ {
+ auto tracks = mLocalStream->GetAudioTracks();
+ for (auto& track : tracks)
+ {
+ mLocalStream->RemoveTrack(track);
+ }
+ mLocalStream = nullptr;
+ }
+ mPeerConnection = nullptr;
+
+ for (auto &observer : mSignalingObserverList)
+ {
+ observer->OnPeerConnectionClosed();
+ }
}
});
}
@@ -811,7 +825,6 @@ bool LLWebRTCPeerConnectionImpl::initializeConnection(const LLWebRTCPeerConnecti
bool LLWebRTCPeerConnectionImpl::shutdownConnection()
{
- mClosing = true;
terminate();
return true;
}
diff --git a/indra/llwebrtc/llwebrtc.h b/indra/llwebrtc/llwebrtc.h
index ac71e0c744..ecbab81538 100644
--- a/indra/llwebrtc/llwebrtc.h
+++ b/indra/llwebrtc/llwebrtc.h
@@ -212,6 +212,9 @@ class LLWebRTCSignalingObserver
// Called when a connection enters a failure state and renegotiation is needed.
virtual void OnRenegotiationNeeded() = 0;
+ // Called when a peer connection has shut down
+ virtual void OnPeerConnectionClosed() = 0;
+
// Called when the audio channel has been established and audio
// can begin.
virtual void OnAudioEstablished(LLWebRTCAudioInterface *audio_interface) = 0;
diff --git a/indra/llwebrtc/llwebrtc_impl.h b/indra/llwebrtc/llwebrtc_impl.h
index 984aaef734..448d36e3ea 100644
--- a/indra/llwebrtc/llwebrtc_impl.h
+++ b/indra/llwebrtc/llwebrtc_impl.h
@@ -355,8 +355,6 @@ class LLWebRTCPeerConnectionImpl : public LLWebRTCPeerConnectionInterface,
LLWebRTCImpl * mWebRTCImpl;
- bool mClosing;
-
rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> mPeerConnectionFactory;
bool mMute;
diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp
index c6868ffeda..ed61c75154 100644
--- a/indra/newview/llfloaterimsession.cpp
+++ b/indra/newview/llfloaterimsession.cpp
@@ -94,6 +94,7 @@ LLFloaterIMSession::LLFloaterIMSession(const LLUUID& session_id)
mEnableCallbackRegistrar.add("Avatar.EnableGearItem", boost::bind(&LLFloaterIMSession::enableGearMenuItem, this, _2));
mCommitCallbackRegistrar.add("Avatar.GearDoToSelected", boost::bind(&LLFloaterIMSession::GearDoToSelected, this, _2));
mEnableCallbackRegistrar.add("Avatar.CheckGearItem", boost::bind(&LLFloaterIMSession::checkGearMenuItem, this, _2));
+ mVoiceChannelChanged = LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&LLFloaterIMSession::onVoiceChannelChanged, this, _1));
setDocked(true);
}
@@ -292,6 +293,8 @@ LLFloaterIMSession::~LLFloaterIMSession()
}
LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::IM, this);
+
+ mVoiceChannelChanged.disconnect();
}
@@ -521,6 +524,14 @@ void LLFloaterIMSession::sendParticipantsAddedNotification(const uuid_vec_t& uui
sendMsg(getString(uuids.size() > 1 ? "multiple_participants_added" : "participant_added", args));
}
+void LLFloaterIMSession::onVoiceChannelChanged(const LLUUID &session_id)
+{
+ if (session_id == mSessionID)
+ {
+ boundVoiceChannel();
+ }
+}
+
void LLFloaterIMSession::boundVoiceChannel()
{
LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID);
diff --git a/indra/newview/llfloaterimsession.h b/indra/newview/llfloaterimsession.h
index fc431f3ced..15b31e797f 100644
--- a/indra/newview/llfloaterimsession.h
+++ b/indra/newview/llfloaterimsession.h
@@ -161,6 +161,8 @@ private:
void onCallButtonClicked();
+ void onVoiceChannelChanged(const LLUUID &session_id);
+
void boundVoiceChannel();
// Add the "User is typing..." indicator.
@@ -195,6 +197,9 @@ private:
uuid_vec_t mInvitedParticipants;
uuid_vec_t mPendingParticipants;
+ // notification when the voice channel is swapped out from beneath us.
+ boost::signals2::connection mVoiceChannelChanged;
+
// connection to voice channel state change signal
boost::signals2::connection mVoiceChannelStateChangeConnection;
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index c9b4454f3f..5e7814df51 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -789,10 +789,15 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id,
void LLIMModel::LLIMSession::initVoiceChannel(const LLSD& voiceChannelInfo)
{
- mVoiceChannelStateChangeConnection.disconnect();
if (mVoiceChannel)
{
+ if (mVoiceChannel->isThisVoiceChannel(voiceChannelInfo))
+ {
+ return;
+ }
+ mVoiceChannelStateChangeConnection.disconnect();
+
mVoiceChannel->deactivate();
delete mVoiceChannel;
@@ -1823,7 +1828,7 @@ EInstantMessage LLIMModel::getType(const LLUUID& session_id) const
return session->mType;
}
-LLVoiceChannel* LLIMModel::getVoiceChannel( const LLUUID& session_id, const LLSD& voice_channel_info ) const
+LLVoiceChannel* LLIMModel::getVoiceChannel( const LLUUID& session_id) const
{
LLIMSession* session = findIMSession(session_id);
if (!session)
@@ -1831,14 +1836,6 @@ LLVoiceChannel* LLIMModel::getVoiceChannel( const LLUUID& session_id, const LLSD
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;
}
@@ -2966,10 +2963,6 @@ void LLIncomingCallDialog::processCallResponse(S32 response, const LLSD &payload
LLUUID session_id = payload["session_id"].asUUID();
LLUUID caller_id = payload["caller_id"].asUUID();
std::string session_name = payload["session_name"].asString();
- if (session_name.empty())
- {
- session_name = payload["caller_name"].asString();
- }
EInstantMessage type = (EInstantMessage)payload["type"].asInteger();
LLIMMgr::EInvitationType inv_type = (LLIMMgr::EInvitationType)payload["inv_type"].asInteger();
bool voice = true;
@@ -2984,6 +2977,10 @@ void LLIncomingCallDialog::processCallResponse(S32 response, const LLSD &payload
{
if (type == IM_SESSION_P2P_INVITE)
{
+ if (session_name.empty())
+ {
+ session_name = payload["caller_name"].asString();
+ }
// create a normal IM session
session_id = gIMMgr->addP2PSession(
session_name, caller_id, payload["voice_channel_info"]);
@@ -3401,8 +3398,9 @@ LLUUID LLIMMgr::addSession(
im_floater->reloadMessages();
}
}
+ LLIMModel::LLIMSession *session = LLIMModel::getInstance()->findIMSession(session_id);
- bool new_session = (LLIMModel::getInstance()->findIMSession(session_id) == NULL);
+ bool new_session = (session == NULL);
//works only for outgoing ad-hoc sessions
if (new_session &&
@@ -3425,6 +3423,7 @@ LLUUID LLIMMgr::addSession(
//Notifies observers that the session was already added
else
{
+ session->initVoiceChannel(voiceChannelInfo);
std::string session_name = LLIMModel::getInstance()->getName(session_id);
LLIMMgr::getInstance()->notifyObserverSessionActivated(session_id, session_name, other_participant_id);
}
@@ -3846,8 +3845,12 @@ void LLIMMgr::removeSessionObserver(LLIMSessionObserver *observer)
bool LLIMMgr::startCall(const LLUUID& session_id, LLVoiceChannel::EDirection direction, const LLSD& voice_channel_info)
{
- LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(session_id, voice_channel_info);
+ LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(session_id);
if (!voice_channel) return false;
+ if (!voice_channel_info.isUndefined())
+ {
+ voice_channel->setChannelInfo(voice_channel_info);
+ }
voice_channel->setCallDirection(direction);
voice_channel->activate();
return true;
@@ -3855,7 +3858,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, LLSD());
+ LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(session_id);
if (!voice_channel) return false;
voice_channel->deactivate();
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index 16444a6755..e4e42e8f0d 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -287,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 LLSD& voice_channel_info = LLSD()) const;
+ LLVoiceChannel* getVoiceChannel(const LLUUID& session_id) const;
/**
* Get im speaker manager for the session specified by session_id
diff --git a/indra/newview/llvoicechannel.h b/indra/newview/llvoicechannel.h
index adc387e22d..62aae59fff 100644
--- a/indra/newview/llvoicechannel.h
+++ b/indra/newview/llvoicechannel.h
@@ -93,6 +93,8 @@ public:
void setCallDirection(EDirection direction) {mCallDirection = direction;}
EDirection getCallDirection() {return mCallDirection;}
+ bool isThisVoiceChannel(const LLSD &voiceChannelInfo) { return LLVoiceClient::getInstance()->compareChannels(mChannelInfo, voiceChannelInfo); }
+
static LLVoiceChannel* getChannelByID(const LLUUID& session_id);
static LLVoiceChannel* getCurrentVoiceChannel();
@@ -115,7 +117,7 @@ public:
EState mState;
std::string mSessionName;
LLSD mNotifyArgs;
- LLSD mChannelInfo;
+ LLSD mChannelInfo;
// true if call was ended by agent
bool mCallEndedByAgent;
bool mIgnoreNextSessionLeave;
diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp
index 8bd3897761..e2d75e244f 100644
--- a/indra/newview/llvoiceclient.cpp
+++ b/indra/newview/llvoiceclient.cpp
@@ -157,7 +157,6 @@ LLVoiceClient::LLVoiceClient(LLPumpIO *pump)
LLVoiceClient::~LLVoiceClient()
{
- llassert(!mSpatialVoiceModule);
}
void LLVoiceClient::init(LLPumpIO *pump)
@@ -540,9 +539,11 @@ LLVoiceP2POutgoingCallInterface *LLVoiceClient::getOutgoingCallInterface(const L
LLVoiceVersionInfo versionInfo = LLVoiceClient::getInstance()->getVersion();
voice_server_type = versionInfo.internalVoiceServerType;
}
- if (voiceChannelInfo.has("voice_server_type"))
+ if (voiceChannelInfo.has("voice_server_type") && voiceChannelInfo["voice_server_type"] != voice_server_type)
{
- voice_server_type = voiceChannelInfo["voice_server_type"].asString();
+ // there's a mismatch between what the peer is offering and what our server
+ // can handle, so downgrade to vivox
+ voice_server_type = VIVOX_VOICE_SERVER_TYPE;
}
LLVoiceModuleInterface *module = getVoiceModule(voice_server_type);
return dynamic_cast<LLVoiceP2POutgoingCallInterface *>(module);
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index 6bbb2f24a6..fe9df190c1 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -6363,7 +6363,8 @@ void LLVivoxVoiceClient::predAvatarNameResolution(const LLVivoxVoiceClient::sess
session->mCallerID,
session->mName,
IM_SESSION_P2P_INVITE,
- LLIMMgr::INVITATION_TYPE_VOICE);
+ LLIMMgr::INVITATION_TYPE_VOICE,
+ session->getVoiceChannelInfo());
}
}
}
diff --git a/indra/newview/llvoicewebrtc.cpp b/indra/newview/llvoicewebrtc.cpp
index e72d5e6066..ddad470149 100644
--- a/indra/newview/llvoicewebrtc.cpp
+++ b/indra/newview/llvoicewebrtc.cpp
@@ -2344,6 +2344,19 @@ void LLVoiceWebRTCConnection::OnRenegotiationNeeded()
});
}
+// callback from llwebrtc
+void LLVoiceWebRTCConnection::OnPeerConnectionClosed()
+{
+ LL::WorkQueue::postMaybe(mMainQueue,
+ [=] {
+ LL_DEBUGS("Voice") << "Peer connection has closed." << LL_ENDL;
+ if (mVoiceConnectionState == VOICE_STATE_WAIT_FOR_CLOSE)
+ {
+ setVoiceConnectionState(VOICE_STATE_CLOSED);
+ mOutstandingRequests--;
+ }
+ });
+}
void LLVoiceWebRTCConnection::setMuteMic(bool muted)
{
@@ -2458,7 +2471,6 @@ void LLVoiceWebRTCConnection::breakVoiceConnectionCoro()
httpOpts->setWantHeaders(true);
mOutstandingRequests++;
- setVoiceConnectionState(VOICE_STATE_WAIT_FOR_EXIT);
// tell the server to shut down the connection as a courtesy.
// shutdownConnection will drop the WebRTC connection which will
@@ -2466,10 +2478,7 @@ void LLVoiceWebRTCConnection::breakVoiceConnectionCoro()
LLSD result = httpAdapter->postAndSuspend(httpRequest, url, body, httpOpts);
mOutstandingRequests--;
- if (!LLWebRTCVoiceClient::isShuttingDown())
- {
- setVoiceConnectionState(VOICE_STATE_SESSION_EXIT);
- }
+ setVoiceConnectionState(VOICE_STATE_SESSION_EXIT);
}
// Tell the simulator to tell the Secondlife WebRTC server that we want a voice
@@ -2732,6 +2741,7 @@ bool LLVoiceWebRTCConnection::connectionStateMachine()
break;
case VOICE_STATE_DISCONNECT:
+ setVoiceConnectionState(VOICE_STATE_WAIT_FOR_EXIT);
LLCoros::instance().launch("LLVoiceWebRTCConnection::breakVoiceConnectionCoro",
boost::bind(&LLVoiceWebRTCConnection::breakVoiceConnectionCoro, this));
break;
@@ -2741,8 +2751,13 @@ bool LLVoiceWebRTCConnection::connectionStateMachine()
case VOICE_STATE_SESSION_EXIT:
{
+ setVoiceConnectionState(VOICE_STATE_WAIT_FOR_CLOSE);
+ mOutstandingRequests++;
mWebRTCPeerConnectionInterface->shutdownConnection();
-
+ break;
+ case VOICE_STATE_WAIT_FOR_CLOSE:
+ break;
+ case VOICE_STATE_CLOSED:
if (!mShutDown)
{
mVoiceConnectionState = VOICE_STATE_START_SESSION;
diff --git a/indra/newview/llvoicewebrtc.h b/indra/newview/llvoicewebrtc.h
index c417dfe329..fcd4c04e98 100644
--- a/indra/newview/llvoicewebrtc.h
+++ b/indra/newview/llvoicewebrtc.h
@@ -585,6 +585,7 @@ class LLVoiceWebRTCConnection :
void OnIceCandidate(const llwebrtc::LLWebRTCIceCandidate &candidate) override;
void OnOfferAvailable(const std::string &sdp) override;
void OnRenegotiationNeeded() override;
+ void OnPeerConnectionClosed() override;
void OnAudioEstablished(llwebrtc::LLWebRTCAudioInterface *audio_interface) override;
//@}
@@ -640,13 +641,15 @@ class LLVoiceWebRTCConnection :
VOICE_STATE_DISCONNECT = 0x100,
VOICE_STATE_WAIT_FOR_EXIT = 0x200,
VOICE_STATE_SESSION_EXIT = 0x400,
- VOICE_STATE_SESSION_STOPPING = 0x780
+ VOICE_STATE_WAIT_FOR_CLOSE = 0x800,
+ VOICE_STATE_CLOSED = 0x1000,
+ VOICE_STATE_SESSION_STOPPING = 0x1F80
} EVoiceConnectionState;
EVoiceConnectionState mVoiceConnectionState;
LL::WorkQueue::weak_t mMainQueue;
- void setVoiceConnectionState(EVoiceConnectionState new_voice_connection_state)
+ void setVoiceConnectionState(EVoiceConnectionState new_voice_connection_state)
{
if (new_voice_connection_state & VOICE_STATE_SESSION_STOPPING)
{