diff options
-rw-r--r-- | indra/llwebrtc/llwebrtc.cpp | 51 | ||||
-rw-r--r-- | indra/llwebrtc/llwebrtc.h | 3 | ||||
-rw-r--r-- | indra/llwebrtc/llwebrtc_impl.h | 2 | ||||
-rw-r--r-- | indra/newview/llfloaterimsession.cpp | 11 | ||||
-rw-r--r-- | indra/newview/llfloaterimsession.h | 5 | ||||
-rw-r--r-- | indra/newview/llimview.cpp | 37 | ||||
-rw-r--r-- | indra/newview/llimview.h | 2 | ||||
-rw-r--r-- | indra/newview/llvoicechannel.h | 4 | ||||
-rw-r--r-- | indra/newview/llvoiceclient.cpp | 7 | ||||
-rw-r--r-- | indra/newview/llvoicevivox.cpp | 3 | ||||
-rw-r--r-- | indra/newview/llvoicewebrtc.cpp | 27 | ||||
-rw-r--r-- | indra/newview/llvoicewebrtc.h | 7 |
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) { |