diff options
| author | Roxanne Skelly <roxie@lindenlab.com> | 2024-05-19 22:18:55 -0700 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-05-19 22:18:55 -0700 | 
| commit | f51797f088808029745161854aa86b775f041a64 (patch) | |
| tree | 2dc638dae2efac22cc3b4783b9ff0a371d58a044 | |
| parent | be19e495c5483c06b9b90dd18bf8ebbe7ceaa336 (diff) | |
| parent | ddbd1ab47ea6cd76ed3e6bf32ffaeb73a32b4a97 (diff) | |
Merge pull request #1449 from secondlife/roxie/webrtc-voice
Fix issue where groups/adhoc chats were named with the initiators display name.
| -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)          { | 
