diff options
Diffstat (limited to 'indra/newview')
-rw-r--r-- | indra/newview/llagent.cpp | 6 | ||||
-rw-r--r-- | indra/newview/llappviewer.cpp | 2 | ||||
-rw-r--r-- | indra/newview/llconversationview.cpp | 2 | ||||
-rw-r--r-- | indra/newview/llfloaterimsession.cpp | 2 | ||||
-rw-r--r-- | indra/newview/llfloaterimsession.h | 3 | ||||
-rw-r--r-- | indra/newview/llimview.cpp | 258 | ||||
-rw-r--r-- | indra/newview/llimview.h | 28 | ||||
-rw-r--r-- | indra/newview/llpanelgroup.cpp | 2 | ||||
-rw-r--r-- | indra/newview/llpanelgroup.h | 2 | ||||
-rw-r--r-- | indra/newview/llpanelpeople.cpp | 2 | ||||
-rw-r--r-- | indra/newview/llpanelpeople.h | 2 | ||||
-rw-r--r-- | indra/newview/llpanelprofile.cpp | 2 | ||||
-rw-r--r-- | indra/newview/llpanelprofile.h | 2 | ||||
-rw-r--r-- | indra/newview/llvoavatar.cpp | 12 | ||||
-rw-r--r-- | indra/newview/llvoavatar.h | 4 | ||||
-rw-r--r-- | indra/newview/llvoicechannel.cpp | 185 | ||||
-rw-r--r-- | indra/newview/llvoicechannel.h | 68 | ||||
-rw-r--r-- | indra/newview/llvoiceclient.cpp | 521 | ||||
-rw-r--r-- | indra/newview/llvoiceclient.h | 122 | ||||
-rw-r--r-- | indra/newview/llvoicevivox.cpp | 425 | ||||
-rw-r--r-- | indra/newview/llvoicevivox.h | 67 | ||||
-rw-r--r-- | indra/newview/llvoicewebrtc.cpp | 205 | ||||
-rw-r--r-- | indra/newview/llvoicewebrtc.h | 59 |
23 files changed, 737 insertions, 1244 deletions
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 3853aaa8fd..ca27dbd818 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -311,7 +311,7 @@ bool LLAgent::isActionAllowed(const LLSD& sdname) } else { - allow_agent_voice = channel->isActive() && channel->callStarted(); + allow_agent_voice = channel->isActive(); } } @@ -4078,10 +4078,6 @@ bool LLAgent::teleportCore(bool is_local) } make_ui_sound("UISndTeleportOut"); - // MBW -- Let the voice client know a teleport has begun so it can leave the existing channel. - // This was breaking the case of teleporting within a single sim. Backing it out for now. -// LLVoiceClient::getInstance()->leaveChannel(); - return true; } diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 9691bb9a8c..c079b3d1a1 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -5121,7 +5121,7 @@ void LLAppViewer::sendLogoutRequest() if(LLVoiceClient::instanceExists()) { - LLVoiceClient::getInstance()->leaveChannel(); + LLVoiceClient::getInstance()->setVoiceEnabled(false); } } } diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp index 48c7df40df..42194c9c16 100644 --- a/indra/newview/llconversationview.cpp +++ b/indra/newview/llconversationview.cpp @@ -57,7 +57,7 @@ public: : conversation(conv) {} - virtual void onChange(EStatusType status, const std::string &channelURI, bool proximal) + virtual void onChange(EStatusType status, const LLSD& channelInfo, bool proximal) { conversation->showVoiceIndicator(conversation && status != STATUS_JOINING diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp index ee9dc35283..1b04db89c4 100644 --- a/indra/newview/llfloaterimsession.cpp +++ b/indra/newview/llfloaterimsession.cpp @@ -550,7 +550,7 @@ void LLFloaterIMSession::onCallButtonClicked() } } -void LLFloaterIMSession::onChange(EStatusType status, const std::string &channelURI, bool proximal) +void LLFloaterIMSession::onChange(EStatusType status, const LLSD& channelInfo, bool proximal) { if(status != STATUS_JOINING && status != STATUS_LEFT_CHANNEL) { diff --git a/indra/newview/llfloaterimsession.h b/indra/newview/llfloaterimsession.h index 28464fc14b..fc431f3ced 100644 --- a/indra/newview/llfloaterimsession.h +++ b/indra/newview/llfloaterimsession.h @@ -114,8 +114,7 @@ public: // Implements LLVoiceClientStatusObserver::onChange() to enable the call // button when voice is available - void onChange(EStatusType status, const std::string &channelURI, - bool proximal); + void onChange(EStatusType status, const LLSD& channelInfo, bool proximal); virtual LLTransientFloaterMgr::ETransientGroup getGroup() { return LLTransientFloaterMgr::IM; } virtual void onVoiceChannelStateChanged( diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 1c8cdfd641..a675c44274 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -111,7 +111,7 @@ BOOL LLSessionTimeoutTimer::tick() { gIMMgr->showSessionStartError("session_initialization_timed_out_error", mSessionId); } - return TRUE; + return TRUE; } @@ -140,7 +140,7 @@ void process_dnd_im(const LLSD& notification) name, IM_NOTHING_SPECIAL, fromID, - false, + LLSD(), false); //will need slight refactor to retrieve whether offline message or not (assume online for now) } @@ -411,6 +411,9 @@ void startConferenceCoro(std::string url, postData["method"] = "start conference"; postData["session-id"] = tempSessionId; postData["params"] = agents; + LLSD altParams; + altParams["voice_server_type"] = gSavedSettings.getString("VoiceServerType"); + postData["alt_params"] = altParams; LLSD result = httpAdapter->postAndSuspend(httpRequest, url, postData); @@ -450,6 +453,9 @@ void startP2PCoro(std::string url, LLUUID sessionID, LLUUID creatorId, LLUUID ot postData["method"] = "start p2p"; postData["session-id"] = sessionID; postData["params"] = otherParticipantId; + LLSD altParams; + altParams["voice_server_type"] = gSavedSettings.getString("VoiceServerType"); + postData["alt_params"] = altParams; LLSD result = httpAdapter->postAndSuspend(httpRequest, url, postData); @@ -458,7 +464,7 @@ void startP2PCoro(std::string url, LLUUID sessionID, LLUUID creatorId, LLUUID ot if (!status) { - LL_WARNS("LLIMModel") << "Failed to start conference" << LL_ENDL; + LL_WARNS("LLIMModel") << "Failed to start conference:" << postData << "->" << result << LL_ENDL; // try an "old school" way. // *TODO: What about other error status codes? 4xx 5xx? if (status == LLCore::HttpStatus(HTTP_BAD_REQUEST)) @@ -675,7 +681,13 @@ LLIMModel::LLIMModel() LLCallDialogManager::instance(); } -LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type, const LLUUID& other_participant_id, const uuid_vec_t& ids, bool voice, bool has_offline_msg) +LLIMModel::LLIMSession::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) : mSessionID(session_id), mName(name), mType(type), @@ -690,24 +702,30 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string& mCallBackEnabled(true), mTextIMPossible(true), mStartCallOnInitialize(false), - mStartedAsIMCall(voice), + mStartedAsIMCall(!voiceChannelInfo.isUndefined()), mIsDNDsend(false), mAvatarNameCacheConnection() { // set P2P type by default - mSessionType = P2P_SESSION; + mSessionType = P2P_SESSION; + bool p2pAsAdhocCall = false; if (IM_NOTHING_SPECIAL == mType || IM_SESSION_P2P_INVITE == mType) { - if (LLVoiceClient::getInstance()->hasP2PInterface()) + 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); + mVoiceChannel = new LLVoiceChannelP2P(session_id, name, other_participant_id, outgoingInterface); + mVoiceChannel->setChannelInfo(voiceChannelInfo); } else { + p2pAsAdhocCall = true; mVoiceChannel = new LLVoiceChannelGroup(session_id, name, true); } } @@ -741,8 +759,7 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string& //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)) + if (!LLIMModel::getInstance()->sendStartSession(mSessionID, mOtherParticipantID, mInitialTargetIDs, mType, p2pAsAdhocCall)) { //we don't need to wait for any responses //so we're already initialized @@ -891,22 +908,6 @@ LLIMModel::LLIMSession::~LLIMSession() delete mSpeakers; mSpeakers = NULL; - // End the text IM session if necessary - if(LLVoiceClient::getInstance() && mOtherParticipantID.notNull()) - { - switch(mType) - { - case IM_NOTHING_SPECIAL: - case IM_SESSION_P2P_INVITE: - LLVoiceClient::getInstance()->endUserIMSession(mOtherParticipantID); - break; - - default: - // Appease the linux compiler - break; - } - } - mVoiceChannelStateChangeConnection.disconnect(); // HAVE to do this here -- if it happens in the LLVoiceChannel destructor it will call the wrong version (since the object's partially deconstructed at that point). @@ -1481,7 +1482,7 @@ void LLIMModel::testMessages() //session name should not be empty bool LLIMModel::newSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type, - const LLUUID& other_participant_id, const uuid_vec_t& ids, bool voice, bool has_offline_msg) + const LLUUID& other_participant_id, const uuid_vec_t& ids, const LLSD& voiceChannelInfo, bool has_offline_msg) { if (name.empty()) { @@ -1495,7 +1496,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, voice, has_offline_msg); + LLIMSession* session = new LLIMSession(session_id, name, type, other_participant_id, ids, voiceChannelInfo, has_offline_msg); mId2SessionMap[session_id] = session; // When notifying observer, name of session is used instead of "name", because they may not be the @@ -1507,11 +1508,11 @@ bool LLIMModel::newSession(const LLUUID& session_id, const std::string& name, co } -bool LLIMModel::newSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type, const LLUUID& other_participant_id, bool voice, bool has_offline_msg) +bool LLIMModel::newSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type, const LLUUID& other_participant_id, const LLSD& voiceChannelInfo, bool has_offline_msg) { uuid_vec_t ids; ids.push_back(other_participant_id); - return newSession(session_id, name, type, other_participant_id, ids, voice, has_offline_msg); + return newSession(session_id, name, type, other_participant_id, ids, voiceChannelInfo, has_offline_msg); } bool LLIMModel::clearSession(const LLUUID& session_id) @@ -2060,7 +2061,8 @@ bool LLIMModel::sendStartSession( const LLUUID& temp_session_id, const LLUUID& other_participant_id, const uuid_vec_t& ids, - EInstantMessage dialog) + EInstantMessage dialog, + bool p2p_as_adhoc_call) { if ( dialog == IM_SESSION_GROUP_START ) { @@ -2076,7 +2078,7 @@ bool LLIMModel::sendStartSession( return true; } - else if (dialog == IM_SESSION_CONFERENCE_START ) + else if ((dialog == IM_SESSION_CONFERENCE_START ) || p2p_as_adhoc_call) { LLSD agents; for (int i = 0; i < (S32) ids.size(); i++) @@ -2107,27 +2109,16 @@ 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)) && !LLVoiceClient::getInstance()->hasP2PInterface()) + else if ((dialog == IM_SESSION_P2P_INVITE) || (dialog == IM_NOTHING_SPECIAL)) { - LLSD agents; - for (int i = 0; i < (S32) ids.size(); i++) - { - agents.append(ids[i]); - } - - // we have a new way of starting conference calls now LLViewerRegion *region = gAgent.getRegion(); if (region) { std::string url = region->getCapability("ChatSessionRequest"); - - LLCoros::instance().launch( - "startP2P", - boost::bind(&startP2PCoro, url, temp_session_id, gAgent.getID(), other_participant_id)); + LLCoros::instance().launch("startP2P", boost::bind(&startP2PCoro, url, temp_session_id, gAgent.getID(), other_participant_id)); } return true; } - return false; } @@ -2720,21 +2711,21 @@ mAvatarNameCacheConnection() void LLIncomingCallDialog::onLifetimeExpired() { - std::string session_handle = mPayload["session_handle"].asString(); - if (LLVoiceClient::getInstance()->isValidChannel(session_handle)) - { - // restart notification's timer if call is still valid - mLifetimeTimer.start(); - } - else - { - // close invitation if call is already not valid - mLifetimeTimer.stop(); - LLUUID session_id = mPayload["session_id"].asUUID(); - gIMMgr->clearPendingAgentListUpdates(session_id); - gIMMgr->clearPendingInvitation(session_id); - closeFloater(); - } + LLVoiceP2PIncomingCallInterfacePtr call = LLVoiceClient::getInstance()->getIncomingCallInterface(mPayload["voice_session_info"]); + if (call) + { + // restart notification's timer if call is still valid + mLifetimeTimer.start(); + } + else + { + // close invitation if call is already not valid + mLifetimeTimer.stop(); + LLUUID session_id = mPayload["session_id"].asUUID(); + gIMMgr->clearPendingAgentListUpdates(session_id); + gIMMgr->clearPendingInvitation(session_id); + closeFloater(); + } } BOOL LLIncomingCallDialog::postBuild() @@ -2914,10 +2905,7 @@ void LLIncomingCallDialog::processCallResponse(S32 response, const LLSD &payload { // create a normal IM session session_id = gIMMgr->addP2PSession( - session_name, - caller_id, - payload["session_handle"].asString(), - payload["session_uri"].asString()); + session_name, caller_id, payload["voice_channel_info"]); if (voice) { @@ -2997,11 +2985,11 @@ void LLIncomingCallDialog::processCallResponse(S32 response, const LLSD &payload { if (type == IM_SESSION_P2P_INVITE) { - if(LLVoiceClient::getInstance()) - { - std::string s = payload["session_handle"].asString(); - LLVoiceClient::getInstance()->declineInvite(s); - } + LLVoiceP2PIncomingCallInterfacePtr call = LLVoiceClient::getInstance()->getIncomingCallInterface(payload["voice_session_info"]); + if (call) + { + call->declineInvite(); + } } else { @@ -3023,90 +3011,6 @@ void LLIncomingCallDialog::processCallResponse(S32 response, const LLSD &payload } } -bool inviteUserResponse(const LLSD& notification, const LLSD& response) -{ - if (!gIMMgr) - return false; - - const LLSD& payload = notification["payload"]; - LLUUID session_id = payload["session_id"].asUUID(); - EInstantMessage type = (EInstantMessage)payload["type"].asInteger(); - LLIMMgr::EInvitationType inv_type = (LLIMMgr::EInvitationType)payload["inv_type"].asInteger(); - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - switch(option) - { - case 0: // accept - { - if (type == IM_SESSION_P2P_INVITE) - { - // create a normal IM session - session_id = gIMMgr->addP2PSession( - payload["session_name"].asString(), - payload["caller_id"].asUUID(), - payload["session_handle"].asString(), - payload["session_uri"].asString()); - - gIMMgr->startCall(session_id); - - gIMMgr->clearPendingAgentListUpdates(session_id); - gIMMgr->clearPendingInvitation(session_id); - } - else - { - gIMMgr->addSession( - payload["session_name"].asString(), - type, - session_id, true); - - std::string url = gAgent.getRegion()->getCapability( - "ChatSessionRequest"); - - LLCoros::instance().launch("chatterBoxInvitationCoro", - boost::bind(&chatterBoxInvitationCoro, url, - session_id, inv_type)); - } - } - break; - case 2: // mute (also implies ignore, so this falls through to the "ignore" case below) - { - // mute the sender of this invite - if (!LLMuteList::getInstance()->isMuted(payload["caller_id"].asUUID())) - { - LLMute mute(payload["caller_id"].asUUID(), payload["caller_name"].asString(), LLMute::AGENT); - LLMuteList::getInstance()->add(mute); - } - } - /* FALLTHROUGH */ - - case 1: // decline - { - if (type == IM_SESSION_P2P_INVITE) - { - std::string s = payload["session_handle"].asString(); - LLVoiceClient::getInstance()->declineInvite(s); - } - else - { - std::string url = gAgent.getRegion()->getCapability( - "ChatSessionRequest"); - - LLSD data; - data["method"] = "decline invitation"; - data["session-id"] = session_id; - LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(url, data, - "Invitation declined.", - "Invitation decline failed."); - } - } - - gIMMgr->clearPendingAgentListUpdates(session_id); - gIMMgr->clearPendingInvitation(session_id); - break; - } - - return false; -} - // // Member Functions // @@ -3178,7 +3082,7 @@ void LLIMMgr::addMessage( { fixed_session_name = av_name.getDisplayName(); } - LLIMModel::getInstance()->newSession(new_session_id, fixed_session_name, dialog, other_participant_id, false, is_offline_msg); + LLIMModel::getInstance()->newSession(new_session_id, fixed_session_name, dialog, other_participant_id, LLSD(), is_offline_msg); LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(new_session_id); if (session) @@ -3338,22 +3242,11 @@ void LLIMMgr::autoStartCallOnStartup(const LLUUID& session_id) } LLUUID LLIMMgr::addP2PSession(const std::string& name, - const LLUUID& other_participant_id, - const std::string& voice_session_handle, - const std::string& caller_uri) + const LLUUID& other_participant_id, + const LLSD& voice_channel_info) { - LLUUID session_id = addSession(name, IM_NOTHING_SPECIAL, other_participant_id, true); - - LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(session_id); - if (speaker_mgr) - { - LLVoiceChannelP2P* voice_channel = dynamic_cast<LLVoiceChannelP2P*>(speaker_mgr->getVoiceChannel()); - if (voice_channel) - { - voice_channel->setSessionHandle(voice_session_handle, caller_uri); - } - } - return session_id; + LL_WARNS("Voice") << "ADD P2P VOICE CHANNEL INFO: " << voice_channel_info << LL_ENDL; + return addSession(name, IM_NOTHING_SPECIAL, other_participant_id, voice_channel_info); } // This adds a session to the talk view. The name is the local name of @@ -3363,11 +3256,12 @@ LLUUID LLIMMgr::addP2PSession(const std::string& name, LLUUID LLIMMgr::addSession( const std::string& name, EInstantMessage dialog, - const LLUUID& other_participant_id, bool voice) + const LLUUID& other_participant_id, + const LLSD& voiceChannelInfo) { std::vector<LLUUID> ids; ids.push_back(other_participant_id); - LLUUID session_id = addSession(name, dialog, other_participant_id, ids, voice); + LLUUID session_id = addSession(name, dialog, other_participant_id, ids, voiceChannelInfo); return session_id; } @@ -3377,7 +3271,8 @@ LLUUID LLIMMgr::addSession( const std::string& name, EInstantMessage dialog, const LLUUID& other_participant_id, - const std::vector<LLUUID>& ids, bool voice, + const std::vector<LLUUID>& ids, + const LLSD& voiceChannelInfo, const LLUUID& floater_id) { if (ids.empty()) @@ -3423,7 +3318,7 @@ LLUUID LLIMMgr::addSession( //Notify observers that a session was added if (new_session) { - LLIMModel::getInstance()->newSession(session_id, name, dialog, other_participant_id, ids, voice); + LLIMModel::getInstance()->newSession(session_id, name, dialog, other_participant_id, ids, voiceChannelInfo); } //Notifies observers that the session was already added else @@ -3484,9 +3379,7 @@ void LLIMMgr::inviteToSession( const std::string& caller_name, EInstantMessage type, EInvitationType inv_type, - const std::string& session_handle, - const std::string& session_uri, - const std::string& voice_server_type) + const LLSD& voice_channel_info) { std::string notify_box_type; // voice invite question is different from default only for group call (EXT-7118) @@ -3528,11 +3421,12 @@ void LLIMMgr::inviteToSession( payload["caller_name"] = caller_name; payload["type"] = type; payload["inv_type"] = inv_type; - payload["session_handle"] = session_handle; - payload["session_uri"] = session_uri; + payload["voice_channel_info"] = voice_channel_info; payload["notify_box_type"] = notify_box_type; payload["question_type"] = question_type; + LL_WARNS("Voice") << "INVITE PAYLOAD: " << payload << LL_ENDL; + //ignore invites from muted residents if (!is_linden) { @@ -3581,7 +3475,7 @@ void LLIMMgr::inviteToSession( fixed_session_name = av_name.getDisplayName(); } } - LLIMModel::getInstance()->newSession(session_id, fixed_session_name, IM_NOTHING_SPECIAL, caller_id, false, false); + LLIMModel::getInstance()->newSession(session_id, fixed_session_name, IM_NOTHING_SPECIAL, caller_id, LLSD(), false); } LLSD args; @@ -3810,7 +3704,6 @@ bool LLIMMgr::startCall(const LLUUID& session_id, LLVoiceChannel::EDirection dir { LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(session_id); if (!voice_channel) return false; - voice_channel->setCallDirection(direction); voice_channel->activate(); return true; @@ -4207,7 +4100,6 @@ public: return; } - std::string voice_server_type = input["body"]["voice"].get("voice_server_type").asString(); BOOL session_type_p2p = input["body"]["voice"].get("p2p").asBoolean(); gIMMgr->inviteToSession( @@ -4217,9 +4109,7 @@ public: input["body"]["from_name"].asString(), session_type_p2p ? IM_SESSION_P2P_INVITE : IM_SESSION_INVITE, LLIMMgr::INVITATION_TYPE_VOICE, - LLStringUtil::null, // session_handle - LLStringUtil::null, - voice_server_type); + input["body"]["voice"]); } else if ( input["body"].has("immediate") ) { diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h index 49c73bd495..8a059e0756 100644 --- a/indra/newview/llimview.h +++ b/indra/newview/llimview.h @@ -80,7 +80,7 @@ public: } SType; LLIMSession(const LLUUID& session_id, const std::string& name, - const EInstantMessage& type, const LLUUID& other_participant_id, const uuid_vec_t& ids, bool voice, bool has_offline_msg); + const EInstantMessage& type, const LLUUID& other_participant_id, const uuid_vec_t& ids, const LLSD& voiceChannelInfo, bool has_offline_msg); virtual ~LLIMSession(); void sessionInitReplyReceived(const LLUUID& new_session_id); @@ -199,10 +199,10 @@ public: * @param name session name should not be empty, will return false if empty */ bool newSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type, const LLUUID& other_participant_id, - const uuid_vec_t& ids, bool voice = false, bool has_offline_msg = false); + const uuid_vec_t& ids, const LLSD& voiceChannelInfo = LLSD(), bool has_offline_msg = false); - bool newSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type, - const LLUUID& other_participant_id, bool voice = false, bool has_offline_msg = false); + bool newSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type, const LLUUID &other_participant_id, + const LLSD &voiceChannelInfo = LLSD(), bool has_offline_msg = false); /** * Remove all session data associated with a session specified by session_id @@ -296,7 +296,7 @@ public: static void sendLeaveSession(const LLUUID& session_id, const LLUUID& other_participant_id); static bool sendStartSession(const LLUUID& temp_session_id, const LLUUID& other_participant_id, - const uuid_vec_t& ids, EInstantMessage dialog); + const uuid_vec_t& ids, EInstantMessage dialog, bool p2p_as_adhoc_call); static void sendTypingState(LLUUID session_id, LLUUID other_participant_id, BOOL typing); static void sendMessage(const std::string& utf8_text, const LLUUID& im_session_id, const LLUUID& other_participant_id, EInstantMessage dialog); @@ -379,7 +379,8 @@ public: // session. LLUUID addSession(const std::string& name, EInstantMessage dialog, - const LLUUID& other_participant_id, bool voice = false); + const LLUUID& other_participant_id, + const LLSD& voiceChannelInfo = LLSD()); // Adds a session using a specific group of starting agents // the dialog type is assumed correct. Returns the uuid of the session. @@ -387,7 +388,8 @@ public: LLUUID addSession(const std::string& name, EInstantMessage dialog, const LLUUID& other_participant_id, - const std::vector<LLUUID>& ids, bool voice = false, + const std::vector<LLUUID> &ids, + const LLSD& voiceChannelInfo = LLSD(), const LLUUID& floater_id = LLUUID::null); /** @@ -397,10 +399,7 @@ public: * @param caller_uri - sip URI of caller. It should be always be passed into the method to avoid * incorrect working of LLVoiceChannel instances. See EXT-2985. */ - LLUUID addP2PSession(const std::string& name, - const LLUUID& other_participant_id, - const std::string& voice_session_handle, - const std::string& caller_uri); + LLUUID addP2PSession(const std::string &name, const LLUUID &other_participant_id, const LLSD &voice_call_info); /** * Leave the session with session id. Send leave session notification @@ -415,10 +414,9 @@ public: const LLUUID& caller, const std::string& caller_name, EInstantMessage type, - EInvitationType inv_type, - const std::string& session_handle = LLStringUtil::null, - const std::string& session_uri = LLStringUtil::null, - const std::string& voice_server_type = LLStringUtil::null); + EInvitationType inv_type, + const LLSD &voice_channel_info = LLSD() + ); void processIMTypingStart(const LLUUID& from_id, const EInstantMessage im_type); void processIMTypingStop(const LLUUID& from_id, const EInstantMessage im_type); diff --git a/indra/newview/llpanelgroup.cpp b/indra/newview/llpanelgroup.cpp index ab255d5215..a06b50390f 100644 --- a/indra/newview/llpanelgroup.cpp +++ b/indra/newview/llpanelgroup.cpp @@ -276,7 +276,7 @@ void LLPanelGroup::changed(LLGroupChange gc) } // virtual -void LLPanelGroup::onChange(EStatusType status, const std::string &channelURI, bool proximal) +void LLPanelGroup::onChange(EStatusType status, const LLSD& channelInfo, bool proximal) { if(status == STATUS_JOINING || status == STATUS_LEFT_CHANNEL) { diff --git a/indra/newview/llpanelgroup.h b/indra/newview/llpanelgroup.h index be40b08a6d..3ca6426887 100644 --- a/indra/newview/llpanelgroup.h +++ b/indra/newview/llpanelgroup.h @@ -62,7 +62,7 @@ public: // Implements LLVoiceClientStatusObserver::onChange() to enable the call // button when voice is available - /*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal); + /*virtual*/ void onChange(EStatusType status, const LLSD& channelInfo, bool proximal); void showNotice(const std::string& subject, const std::string& message, diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp index 13b52e97c5..27019badd2 100644 --- a/indra/newview/llpanelpeople.cpp +++ b/indra/newview/llpanelpeople.cpp @@ -733,7 +733,7 @@ BOOL LLPanelPeople::postBuild() } // virtual -void LLPanelPeople::onChange(EStatusType status, const std::string &channelURI, bool proximal) +void LLPanelPeople::onChange(EStatusType status, const LLSD& channelInfo, bool proximal) { if(status == STATUS_JOINING || status == STATUS_LEFT_CHANNEL) { diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h index 14205cebe2..e4484b66c6 100644 --- a/indra/newview/llpanelpeople.h +++ b/indra/newview/llpanelpeople.h @@ -55,7 +55,7 @@ public: /*virtual*/ bool notifyChildren(const LLSD& info); // Implements LLVoiceClientStatusObserver::onChange() to enable call buttons // when voice is available - /*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal); + /*virtual*/ void onChange(EStatusType status, const LLSD& channelInfo, bool proximal); // internals class Updater; diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index ffbed778c1..132b710620 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -1446,7 +1446,7 @@ void LLPanelProfileSecondLife::changed(U32 mask) } // virtual, called by LLVoiceClient -void LLPanelProfileSecondLife::onChange(EStatusType status, const std::string &channelURI, bool proximal) +void LLPanelProfileSecondLife::onChange(EStatusType status, const LLSD& channelInfo, bool proximal) { if(status == STATUS_JOINING || status == STATUS_LEFT_CHANNEL) { diff --git a/indra/newview/llpanelprofile.h b/indra/newview/llpanelprofile.h index 11632a10ae..ea2bb25ac2 100644 --- a/indra/newview/llpanelprofile.h +++ b/indra/newview/llpanelprofile.h @@ -85,7 +85,7 @@ public: // Implements LLVoiceClientStatusObserver::onChange() to enable the call // button when voice is available - void onChange(EStatusType status, const std::string &channelURI, bool proximal) override; + void onChange(EStatusType status, const LLSD& channelInfo, bool proximal) override; void setAvatarId(const LLUUID& avatar_id) override; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index fee00eb6f4..5d7adb9613 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -614,7 +614,8 @@ BOOL LLVOAvatar::sShowAnimationDebug = FALSE; BOOL LLVOAvatar::sVisibleInFirstPerson = FALSE; F32 LLVOAvatar::sLODFactor = 1.f; F32 LLVOAvatar::sPhysicsLODFactor = 1.f; -BOOL LLVOAvatar::sJointDebug = FALSE; +BOOL LLVOAvatar::sJointDebug = FALSE; +BOOL LLVOAvatar::sLipSyncEnabled = FALSE; F32 LLVOAvatar::sUnbakedTime = 0.f; F32 LLVOAvatar::sUnbakedUpdateTime = 0.f; F32 LLVOAvatar::sGreyTime = 0.f; @@ -1155,6 +1156,7 @@ void LLVOAvatar::initClass() LLControlAvatar::sRegionChangedSlot = gAgent.addRegionChangedCallback(&LLControlAvatar::onRegionChanged); sCloudTexture = LLViewerTextureManager::getFetchedTextureFromFile("cloud-particle.j2c"); + gSavedSettings.getControl("LipSyncEnabled")->getSignal()->connect(boost::bind(&LLVOAvatar::handleVOAvatarPrefsChanged, _2)); } @@ -1162,6 +1164,12 @@ void LLVOAvatar::cleanupClass() { } +bool LLVOAvatar::handleVOAvatarPrefsChanged(const LLSD &newvalue) +{ + sLipSyncEnabled = gSavedSettings.getBOOL("LipSyncEnabled"); + return true; +} + // virtual void LLVOAvatar::initInstance() { @@ -3072,7 +3080,7 @@ void LLVOAvatar::idleUpdateLipSync(bool voice_enabled) // Use the Lipsync_Ooh and Lipsync_Aah morphs for lip sync if ( voice_enabled && mLastRezzedStatus > 0 // no point updating lip-sync for clouds - && (LLVoiceClient::getInstance()->lipSyncEnabled()) + && sLipSyncEnabled && LLVoiceClient::getInstance()->getIsSpeaking( mID ) ) { F32 ooh_morph_amount = 0.0f; diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 48bfd5293a..87c9d468a2 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -106,9 +106,10 @@ public: virtual void markDead(); static void initClass(); // Initialize data that's only init'd once per class. static void cleanupClass(); // Cleanup data that's only init'd once per class. - virtual void initInstance(); // Called after construction to initialize the class. + virtual void initInstance(); // Called after construction to initialize the class. protected: virtual ~LLVOAvatar(); + static bool LLVOAvatar::handleVOAvatarPrefsChanged(const LLSD &newvalue); /** Initialization ** ** @@ -365,6 +366,7 @@ public: static F32 sLODFactor; // user-settable LOD factor static F32 sPhysicsLODFactor; // user-settable physics LOD factor static BOOL sJointDebug; // output total number of joints being touched for each avatar + static BOOL sLipSyncEnabled; static LLPointer<LLViewerTexture> sCloudTexture; diff --git a/indra/newview/llvoicechannel.cpp b/indra/newview/llvoicechannel.cpp index 4ca876bed1..10cccb3671 100644 --- a/indra/newview/llvoicechannel.cpp +++ b/indra/newview/llvoicechannel.cpp @@ -39,7 +39,6 @@ #include "llcorehttputil.h" LLVoiceChannel::voice_channel_map_t LLVoiceChannel::sVoiceChannelMap; -LLVoiceChannel::voice_channel_map_uri_t LLVoiceChannel::sVoiceChannelURIMap; LLVoiceChannel* LLVoiceChannel::sCurrentVoiceChannel = NULL; LLVoiceChannel* LLVoiceChannel::sSuspendedVoiceChannel = NULL; LLVoiceChannel::channel_changed_signal_t LLVoiceChannel::sCurrentVoiceChannelChangedSignal; @@ -89,29 +88,18 @@ LLVoiceChannel::~LLVoiceChannel() } sVoiceChannelMap.erase(mSessionID); - sVoiceChannelURIMap.erase(mURI); } -void LLVoiceChannel::setChannelInfo( - const std::string& uri, - const std::string& credentials) +void LLVoiceChannel::setChannelInfo(const LLSD &channelInfo) { - setURI(uri); - - mCredentials = credentials; + mChannelInfo = channelInfo; if (mState == STATE_NO_CHANNEL_INFO) { - if (mURI.empty()) - { - LLNotificationsUtil::add("VoiceChannelJoinFailed", mNotifyArgs); - LL_WARNS("Voice") << "Received empty URI for channel " << mSessionName << LL_ENDL; - deactivate(); - } - else if (mCredentials.empty()) + if (mChannelInfo.isUndefined()) { LLNotificationsUtil::add("VoiceChannelJoinFailed", mNotifyArgs); - LL_WARNS("Voice") << "Received empty credentials for channel " << mSessionName << LL_ENDL; + LL_WARNS("Voice") << "Received empty channel info for channel " << mSessionName << LL_ENDL; deactivate(); } else @@ -130,11 +118,17 @@ void LLVoiceChannel::setChannelInfo( } } -void LLVoiceChannel::onChange(EStatusType type, const std::string &channelURI, bool proximal) +void LLVoiceChannel::onChange(EStatusType type, const LLSD& channelInfo, bool proximal) { - if (channelURI != mURI) + LL_WARNS("Voice") << channelInfo << LL_ENDL; + LL_WARNS("Voice") << mChannelInfo << LL_ENDL; + if (mChannelInfo.isUndefined()) { - return; + mChannelInfo = channelInfo; + } + if (!LLVoiceClient::getInstance()->compareChannels(mChannelInfo, channelInfo)) + { + return; } if (type < BEGIN_ERROR_STATUS) @@ -193,7 +187,7 @@ void LLVoiceChannel::handleError(EStatusType type) BOOL LLVoiceChannel::isActive() { // only considered active when currently bound channel matches what our channel - return callStarted() && LLVoiceClient::getInstance()->getCurrentChannel() == mURI; + return callStarted() && LLVoiceClient::getInstance()->isCurrentChannel(mChannelInfo); } BOOL LLVoiceChannel::callStarted() @@ -246,10 +240,8 @@ void LLVoiceChannel::activate() // activating the proximal channel between IM calls LLVoiceChannel* old_channel = sCurrentVoiceChannel; sCurrentVoiceChannel = this; - mCallDialogPayload["old_channel_name"] = ""; if (old_channel) { - mCallDialogPayload["old_channel_name"] = old_channel->getSessionName(); old_channel->deactivate(); } } @@ -257,7 +249,7 @@ void LLVoiceChannel::activate() if (mState == STATE_NO_CHANNEL_INFO) { // responsible for setting status to active - getChannelInfo(); + requestChannelInfo(); } else { @@ -270,7 +262,7 @@ void LLVoiceChannel::activate() sCurrentVoiceChannelChangedSignal(this->mSessionID); } -void LLVoiceChannel::getChannelInfo() +void LLVoiceChannel::requestChannelInfo() { // pretend we have everything we need if (sCurrentVoiceChannel == this) @@ -293,20 +285,6 @@ LLVoiceChannel* LLVoiceChannel::getChannelByID(const LLUUID& session_id) } } -//static -LLVoiceChannel* LLVoiceChannel::getChannelByURI(std::string uri) -{ - voice_channel_map_uri_t::iterator found_it = sVoiceChannelURIMap.find(uri); - if (found_it == sVoiceChannelURIMap.end()) - { - return NULL; - } - else - { - return found_it->second; - } -} - LLVoiceChannel* LLVoiceChannel::getCurrentVoiceChannel() { return sCurrentVoiceChannel; @@ -319,13 +297,6 @@ void LLVoiceChannel::updateSessionID(const LLUUID& new_session_id) sVoiceChannelMap.insert(std::make_pair(mSessionID, this)); } -void LLVoiceChannel::setURI(std::string uri) -{ - sVoiceChannelURIMap.erase(mURI); - mURI = uri; - sVoiceChannelURIMap.insert(std::make_pair(mURI, this)); -} - void LLVoiceChannel::setState(EState state) { switch(state) @@ -436,10 +407,8 @@ void LLVoiceChannelGroup::activate() if (callStarted()) { // we have the channel info, just need to use it now - LLVoiceClient::getInstance()->setNonSpatialChannel( - mURI, - mCredentials, - mHangupOnLastLeave); + LLVoiceClient::getInstance()->setNonSpatialChannel(mChannelInfo, + mHangupOnLastLeave); if (!gAgent.isInGroup(mSessionID)) // ad-hoc channel { @@ -473,7 +442,7 @@ void LLVoiceChannelGroup::activate() } } -void LLVoiceChannelGroup::getChannelInfo() +void LLVoiceChannelGroup::requestChannelInfo() { LLViewerRegion* region = gAgent.getRegion(); if (region) @@ -485,17 +454,13 @@ void LLVoiceChannelGroup::getChannelInfo() } } -void LLVoiceChannelGroup::setChannelInfo( - const std::string& uri, - const std::string& credentials) +void LLVoiceChannelGroup::setChannelInfo(const LLSD& channelInfo) { - setURI(uri); - - mCredentials = credentials; + mChannelInfo = channelInfo; if (mState == STATE_NO_CHANNEL_INFO) { - if(!mURI.empty() && !mCredentials.empty()) + if(mChannelInfo.isUndefined()) { setState(STATE_READY); @@ -518,10 +483,8 @@ void LLVoiceChannelGroup::setChannelInfo( else if ( mIsRetrying ) { // we have the channel info, just need to use it now - LLVoiceClient::getInstance()->setNonSpatialChannel( - mURI, - mCredentials, - mHangupOnLastLeave); + LLVoiceClient::getInstance()->setNonSpatialChannel(channelInfo, + mHangupOnLastLeave); } } @@ -530,30 +493,6 @@ void LLVoiceChannelGroup::handleStatusChange(EStatusType type) // status updates switch(type) { - case STATUS_LEFT_CHANNEL: - { - if (!LLVoiceClient::getInstance()->hasP2PInterface()) - { - // we're using group/adhoc for p2p - if (callStarted() && !mIgnoreNextSessionLeave && !sSuspended) - { - // *TODO: use it to show DECLINE voice notification - if (mState == STATE_RINGING) - { - // other user declined call - LLNotificationsUtil::add("P2PCallDeclined", mNotifyArgs); - } - else - { - // other user hung up, so we didn't end the call - mCallEndedByAgent = false; - } - deactivate(); - } - mIgnoreNextSessionLeave = FALSE; - return; - } - } case STATUS_JOINED: mRetries = 3; mIsRetrying = FALSE; @@ -583,7 +522,7 @@ void LLVoiceChannelGroup::handleError(EStatusType status) mIsRetrying = TRUE; mIgnoreNextSessionLeave = TRUE; - getChannelInfo(); + requestChannelInfo(); return; } else @@ -678,15 +617,12 @@ void LLVoiceChannelGroup::voiceCallCapCoro(std::string url) LLSD::map_const_iterator iter; for (iter = result.beginMap(); iter != result.endMap(); ++iter) { - LL_DEBUGS("Voice") << "LLVoiceCallCapResponder::result got " + LL_DEBUGS("Voice") << "LLVoiceChannelGroup::voiceCallCapCoro got " << iter->first << LL_ENDL; } - LL_INFOS("Voice") << "LLVoiceCallCapResponder::result got " << result << LL_ENDL; - - channelp->setChannelInfo( - result["voice_credentials"]["channel_uri"].asString(), - result["voice_credentials"]["channel_credentials"].asString()); + LL_INFOS("Voice") << "LLVoiceChannelGroup::voiceCallCapCoro got " << result << LL_ENDL; + channelp->setChannelInfo(result["voice_credentials"]); } @@ -710,13 +646,14 @@ void LLVoiceChannelProximal::activate() if((LLVoiceChannel::sCurrentVoiceChannel != this) && (LLVoiceChannel::getState() == STATE_CONNECTED)) { // we're connected to a non-spatial channel, so disconnect. - LLVoiceClient::getInstance()->leaveNonSpatialChannel(); + LLVoiceClient::getInstance()->leaveNonSpatialChannel(); } + LLVoiceClient::getInstance()->activateSpatialChannel(true); LLVoiceChannel::activate(); } -void LLVoiceChannelProximal::onChange(EStatusType type, const std::string &channelURI, bool proximal) +void LLVoiceChannelProximal::onChange(EStatusType type, const LLSD& channelInfo, bool proximal) { if (!proximal) { @@ -786,19 +723,22 @@ void LLVoiceChannelProximal::deactivate() { setState(STATE_HUNG_UP); } + LLVoiceClient::getInstance()->activateSpatialChannel(false); } // // LLVoiceChannelP2P // -LLVoiceChannelP2P::LLVoiceChannelP2P(const LLUUID& session_id, const std::string& session_name, const LLUUID& other_user_id) : +LLVoiceChannelP2P::LLVoiceChannelP2P(const LLUUID &session_id, + const std::string &session_name, + const LLUUID &other_user_id, + LLVoiceP2POutgoingCallInterface* outgoing_call_interface) : LLVoiceChannelGroup(session_id, session_name, true), mOtherUserID(other_user_id), - mReceivedCall(FALSE) + mReceivedCall(FALSE), + mOutgoingCallInterface(outgoing_call_interface) { - // make sure URI reflects encoded version of other user's agent id - setURI(LLVoiceClient::getInstance()->sipURIFromID(other_user_id)); } void LLVoiceChannelP2P::handleStatusChange(EStatusType type) @@ -865,23 +805,23 @@ void LLVoiceChannelP2P::activate() if (callStarted()) { // no session handle yet, we're starting the call - if (mSessionHandle.empty()) + if (mIncomingCallInterface == nullptr) { mReceivedCall = FALSE; - LLVoiceClient::getInstance()->callUser(mOtherUserID); + mOutgoingCallInterface->callUser(mOtherUserID); } // otherwise answering the call else { - if (!LLVoiceClient::getInstance()->answerInvite(mSessionHandle)) + if (!mIncomingCallInterface->answerInvite()) { mCallEndedByAgent = false; - mSessionHandle.clear(); + mIncomingCallInterface.reset(); handleError(ERROR_UNKNOWN); return; } - // using the session handle invalidates it. Clear it out here so we can't reuse it by accident. - mSessionHandle.clear(); + // using the incoming call interface invalidates it. Clear it out here so we can't reuse it by accident. + mIncomingCallInterface.reset(); } // Add the party to the list of people with which we've recently interacted. @@ -895,7 +835,17 @@ void LLVoiceChannelP2P::activate() } } -void LLVoiceChannelP2P::getChannelInfo() +void LLVoiceChannelP2P::deactivate() +{ + if (callStarted()) + { + mOutgoingCallInterface->hangup(); + } + LLVoiceChannel::deactivate(); +} + + +void LLVoiceChannelP2P::requestChannelInfo() { // pretend we have everything we need, since P2P doesn't use channel info if (sCurrentVoiceChannel == this) @@ -905,8 +855,9 @@ void LLVoiceChannelP2P::getChannelInfo() } // receiving session from other user who initiated call -void LLVoiceChannelP2P::setSessionHandle(const std::string& handle, const std::string &inURI) +void LLVoiceChannelP2P::setChannelInfo(const LLSD& channel_info) { + mChannelInfo = channel_info; BOOL needs_activate = FALSE; if (callStarted()) { @@ -921,28 +872,16 @@ void LLVoiceChannelP2P::setSessionHandle(const std::string& handle, const std::s { // we are active and have priority, invite the other user again // under the assumption they will join this new session - mSessionHandle.clear(); - LLVoiceClient::getInstance()->callUser(mOtherUserID); + mOutgoingCallInterface->callUser(mOtherUserID); return; } } - - mSessionHandle = handle; - - // The URI of a p2p session should always be the other end's SIP URI. - if(!inURI.empty()) - { - setURI(inURI); - } - else - { - LL_WARNS("Voice") << "incoming SIP URL is not provided. Channel may not work properly." << LL_ENDL; - // See LLVoiceClient::sessionAddedEvent() - setURI(LLVoiceClient::getInstance()->sipURIFromID(mOtherUserID)); - } mReceivedCall = TRUE; - + if (!channel_info.isUndefined()) + { + mIncomingCallInterface = LLVoiceClient::getInstance()->getIncomingCallInterface(channel_info); + } if (needs_activate) { activate(); diff --git a/indra/newview/llvoicechannel.h b/indra/newview/llvoicechannel.h index 84ef3e7c08..dd24c72891 100644 --- a/indra/newview/llvoicechannel.h +++ b/indra/newview/llvoicechannel.h @@ -66,16 +66,14 @@ public: LLVoiceChannel(const LLUUID& session_id, const std::string& session_name); virtual ~LLVoiceChannel(); - /*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal); + virtual void onChange(EStatusType status, const LLSD& channelInfo, bool proximal); virtual void handleStatusChange(EStatusType status); virtual void handleError(EStatusType status); virtual void deactivate(); virtual void activate(); - virtual void setChannelInfo( - const std::string& uri, - const std::string& credentials); - virtual void getChannelInfo(); + virtual void setChannelInfo(const LLSD &channelInfo); + virtual void requestChannelInfo(); virtual BOOL isActive(); virtual BOOL callStarted(); @@ -96,7 +94,6 @@ public: EDirection getCallDirection() {return mCallDirection;} static LLVoiceChannel* getChannelByID(const LLUUID& session_id); - static LLVoiceChannel* getChannelByURI(std::string uri); static LLVoiceChannel* getCurrentVoiceChannel(); static void initClass(); @@ -110,29 +107,24 @@ protected: * Use this method if you want mStateChangedCallback to be executed while state is changed */ void doSetState(const EState& state); - void setURI(std::string uri); // there can be two directions INCOMING and OUTGOING EDirection mCallDirection; - std::string mURI; - std::string mCredentials; LLUUID mSessionID; EState mState; std::string mSessionName; - LLSD mNotifyArgs; - LLSD mCallDialogPayload; + LLSD mNotifyArgs; + LLSD mChannelInfo; // true if call was ended by agent bool mCallEndedByAgent; - BOOL mIgnoreNextSessionLeave; + bool mIgnoreNextSessionLeave; LLHandle<LLPanel> mLoginNotificationHandle; typedef std::map<LLUUID, LLVoiceChannel*> voice_channel_map_t; static voice_channel_map_t sVoiceChannelMap; - typedef std::map<std::string, LLVoiceChannel*> voice_channel_map_uri_t; - static voice_channel_map_uri_t sVoiceChannelURIMap; - + static LLVoiceChannel* sProximalVoiceChannel; static LLVoiceChannel* sCurrentVoiceChannel; static LLVoiceChannel* sSuspendedVoiceChannel; static BOOL sSuspended; @@ -146,14 +138,12 @@ class LLVoiceChannelGroup : public LLVoiceChannel public: LLVoiceChannelGroup(const LLUUID& session_id, const std::string& session_name, BOOL hangup_on_last_leave); - /*virtual*/ void handleStatusChange(EStatusType status); - /*virtual*/ void handleError(EStatusType status); - /*virtual*/ void activate(); - /*virtual*/ void deactivate(); - /*vritual*/ void setChannelInfo( - const std::string& uri, - const std::string& credentials); - /*virtual*/ void getChannelInfo(); + void handleStatusChange(EStatusType status) override; + void handleError(EStatusType status) override; + void activate() override; + void deactivate() override; + void setChannelInfo(const LLSD &channelInfo) override; + void requestChannelInfo() override; protected: virtual void setState(EState state); @@ -171,26 +161,30 @@ class LLVoiceChannelProximal : public LLVoiceChannel, public LLSingleton<LLVoice LLSINGLETON(LLVoiceChannelProximal); public: - /*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal); - /*virtual*/ void handleStatusChange(EStatusType status); - /*virtual*/ void handleError(EStatusType status); - /*virtual*/ BOOL isActive(); - /*virtual*/ void activate(); - /*virtual*/ void deactivate(); + void onChange(EStatusType status, const LLSD& channelInfo, bool proximal) override; + void handleStatusChange(EStatusType status) override; + void handleError(EStatusType status) override; + BOOL isActive() override; + void activate() override; + void deactivate() override; }; class LLVoiceChannelP2P : public LLVoiceChannelGroup { public: - LLVoiceChannelP2P(const LLUUID& session_id, const std::string& session_name, const LLUUID& other_user_id); + LLVoiceChannelP2P(const LLUUID &session_id, + const std::string &session_name, + const LLUUID &other_user_id, + LLVoiceP2POutgoingCallInterface * outgoing_call_interface); - /*virtual*/ void handleStatusChange(EStatusType status); - /*virtual*/ void handleError(EStatusType status); - /*virtual*/ void activate(); - /*virtual*/ void getChannelInfo(); + void handleStatusChange(EStatusType status) override; + void handleError(EStatusType status) override; + void activate() override; + void requestChannelInfo() override; + void deactivate() override; - void setSessionHandle(const std::string& handle, const std::string &inURI); + void setChannelInfo(const LLSD& channel_info); protected: virtual void setState(EState state); @@ -202,10 +196,10 @@ private: * **/ void addToTheRecentPeopleList(); - - std::string mSessionHandle; LLUUID mOtherUserID; BOOL mReceivedCall; + LLVoiceP2POutgoingCallInterface *mOutgoingCallInterface; + LLVoiceP2PIncomingCallInterfacePtr mIncomingCallInterface; }; #endif // LL_VOICECHANNEL_H diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index 3532d8e986..3df94d8ba0 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -113,13 +113,28 @@ std::string LLVoiceClientStatusObserver::status2string(LLVoiceClientStatusObserv return result; } - +LLVoiceModuleInterface *getVoiceModule(const std::string &voice_server_type) +{ + if (voice_server_type == VIVOX_VOICE_SERVER_TYPE || voice_server_type.empty()) + { + return (LLVoiceModuleInterface *) LLVivoxVoiceClient::getInstance(); + } + else if (voice_server_type == WEBRTC_VOICE_SERVER_TYPE) + { + return (LLVoiceModuleInterface *) LLWebRTCVoiceClient::getInstance(); + } + else + { + LLNotificationsUtil::add("VoiceVersionMismatch"); + return nullptr; + } +} /////////////////////////////////////////////////////////////////////////////////////////////// LLVoiceClient::LLVoiceClient(LLPumpIO *pump) : - mVoiceModule(NULL), + mSpatialVoiceModule(NULL), m_servicePump(NULL), mVoiceEffectEnabled(LLCachedControl<bool>(gSavedSettings, "VoiceMorphingEnabled", true)), mVoiceEffectDefault(LLCachedControl<std::string>(gSavedPerAccountSettings, "VoiceEffectDefault", "00000000-0000-0000-0000-000000000000")), @@ -141,7 +156,7 @@ LLVoiceClient::LLVoiceClient(LLPumpIO *pump) LLVoiceClient::~LLVoiceClient() { - llassert(!mVoiceModule); + llassert(!mSpatialVoiceModule); } void LLVoiceClient::init(LLPumpIO *pump) @@ -154,9 +169,9 @@ void LLVoiceClient::init(LLPumpIO *pump) void LLVoiceClient::userAuthorized(const std::string& user_id, const LLUUID &agentID) { - mUserID = user_id; - mAgentID = agentID; gAgent.addRegionChangedCallback(boost::bind(&LLVoiceClient::onRegionChanged, this)); + LLWebRTCVoiceClient::getInstance()->userAuthorized(user_id, agentID); + LLVivoxVoiceClient::getInstance()->userAuthorized(user_id, agentID); } void LLVoiceClient::onRegionChanged() @@ -166,7 +181,7 @@ void LLVoiceClient::onRegionChanged() { LLSD simulatorFeatures; region->getSimulatorFeatures(simulatorFeatures); - setVoiceModule(simulatorFeatures["VoiceServerType"].asString()); + setSpatialVoiceModule(simulatorFeatures["VoiceServerType"].asString()); } else if (region) { @@ -187,44 +202,57 @@ void LLVoiceClient::onSimulatorFeaturesReceived(const LLUUID& region_id) { LLSD simulatorFeatures; region->getSimulatorFeatures(simulatorFeatures); - setVoiceModule(simulatorFeatures["VoiceServerType"].asString()); + setSpatialVoiceModule(simulatorFeatures["VoiceServerType"].asString()); } } -void LLVoiceClient::setVoiceModule(const std::string& voice_server_type) +void LLVoiceClient::setSpatialVoiceModule(const std::string &voice_server_type) { - if (voice_server_type == "vivox" || voice_server_type.empty()) - { - mVoiceModule = (LLVoiceModuleInterface *) LLVivoxVoiceClient::getInstance(); - } - else if (voice_server_type == "webrtc") - { - mVoiceModule = (LLVoiceModuleInterface *) LLWebRTCVoiceClient::getInstance(); - } - else + LLVoiceModuleInterface *module = getVoiceModule(voice_server_type); + if (!module) { - LLNotificationsUtil::add("VoiceVersionMismatch"); - mVoiceModule = nullptr; return; } - mVoiceModule->userAuthorized(mUserID, mAgentID); - updateSettings(); + if (module != mSpatialVoiceModule) + { + if (inProximalChannel()) + { + mSpatialVoiceModule->processChannels(false); + } + module->processChannels(true); + mSpatialVoiceModule = module; + mSpatialVoiceModule->updateSettings(); + } } - +void LLVoiceClient::setNonSpatialVoiceModule(const std::string &voice_server_type) +{ + mNonSpatialVoiceModule = getVoiceModule(voice_server_type); + if (!mNonSpatialVoiceModule) + { + // we don't have a non-spatial voice module, + // so revert to spatial. + if (mSpatialVoiceModule) + { + mSpatialVoiceModule->processChannels(true); + } + return; + } + mNonSpatialVoiceModule->updateSettings(); +} void LLVoiceClient::setHidden(bool hidden) { - if (mVoiceModule) + if (mSpatialVoiceModule) { - mVoiceModule->setHidden(hidden); + mSpatialVoiceModule->setHidden(hidden); } } void LLVoiceClient::terminate() { - if (mVoiceModule) mVoiceModule->terminate(); - mVoiceModule = NULL; + if (mSpatialVoiceModule) mSpatialVoiceModule->terminate(); + mSpatialVoiceModule = NULL; m_servicePump = NULL; // Shutdown speaker volume storage before LLSingletonBase::deleteAll() does it @@ -236,9 +264,9 @@ void LLVoiceClient::terminate() const LLVoiceVersionInfo LLVoiceClient::getVersion() { - if (mVoiceModule) + if (mSpatialVoiceModule) { - return mVoiceModule->getVersion(); + return mSpatialVoiceModule->getVersion(); } else { @@ -258,10 +286,8 @@ void LLVoiceClient::updateSettings() updateMicMuteLogic(); - if (mVoiceModule) - { - mVoiceModule->updateSettings(); - } + LLWebRTCVoiceClient::getInstance()->updateSettings(); + LLVivoxVoiceClient::getInstance()->updateSettings(); } //-------------------------------------------------- @@ -269,117 +295,76 @@ void LLVoiceClient::updateSettings() void LLVoiceClient::tuningStart() { - if (mVoiceModule) mVoiceModule->tuningStart(); + LLWebRTCVoiceClient::getInstance()->tuningStart(); + LLVivoxVoiceClient::getInstance()->tuningStart(); } void LLVoiceClient::tuningStop() { - if (mVoiceModule) mVoiceModule->tuningStop(); + LLWebRTCVoiceClient::getInstance()->tuningStop(); + LLVivoxVoiceClient::getInstance()->tuningStop(); + } bool LLVoiceClient::inTuningMode() { - if (mVoiceModule) - { - return mVoiceModule->inTuningMode(); - } - else - { - return false; - } + return LLWebRTCVoiceClient::getInstance()->inTuningMode(); } void LLVoiceClient::tuningSetMicVolume(float volume) { - if (mVoiceModule) mVoiceModule->tuningSetMicVolume(volume); + LLWebRTCVoiceClient::getInstance()->tuningSetMicVolume(volume); } void LLVoiceClient::tuningSetSpeakerVolume(float volume) { - if (mVoiceModule) mVoiceModule->tuningSetSpeakerVolume(volume); + LLWebRTCVoiceClient::getInstance()->tuningSetSpeakerVolume(volume); } float LLVoiceClient::tuningGetEnergy(void) { - if (mVoiceModule) - { - return mVoiceModule->tuningGetEnergy(); - } - else - { - return 0.0; - } + return LLWebRTCVoiceClient::getInstance()->tuningGetEnergy(); } - //------------------------------------------------ // devices bool LLVoiceClient::deviceSettingsAvailable() -{ - if (mVoiceModule) - { - return mVoiceModule->deviceSettingsAvailable(); - } - else - { - return false; - } +{ + return LLWebRTCVoiceClient::getInstance()->deviceSettingsAvailable(); } bool LLVoiceClient::deviceSettingsUpdated() -{ - if (mVoiceModule) - { - return mVoiceModule->deviceSettingsUpdated(); - } - else - { - return false; - } +{ + return LLWebRTCVoiceClient::getInstance()->deviceSettingsUpdated(); } void LLVoiceClient::refreshDeviceLists(bool clearCurrentList) { - if (mVoiceModule) mVoiceModule->refreshDeviceLists(clearCurrentList); + LLWebRTCVoiceClient::getInstance()->refreshDeviceLists(clearCurrentList); } void LLVoiceClient::setCaptureDevice(const std::string& name) { - if (mVoiceModule) mVoiceModule->setCaptureDevice(name); - + LLWebRTCVoiceClient::getInstance()->setCaptureDevice(name); + LLVivoxVoiceClient::getInstance()->setCaptureDevice(name); } void LLVoiceClient::setRenderDevice(const std::string& name) { - if (mVoiceModule) mVoiceModule->setRenderDevice(name); + LLWebRTCVoiceClient::getInstance()->setRenderDevice(name); + LLVivoxVoiceClient::getInstance()->setRenderDevice(name); } const LLVoiceDeviceList& LLVoiceClient::getCaptureDevices() { - static LLVoiceDeviceList nullCaptureDevices; - if (mVoiceModule) - { - return mVoiceModule->getCaptureDevices(); - } - else - { - return nullCaptureDevices; - } + return LLWebRTCVoiceClient::getInstance()->getCaptureDevices(); } const LLVoiceDeviceList& LLVoiceClient::getRenderDevices() -{ - static LLVoiceDeviceList nullRenderDevices; - if (mVoiceModule) - { - return mVoiceModule->getRenderDevices(); - } - else - { - return nullRenderDevices; - } +{ + return LLWebRTCVoiceClient::getInstance()->getRenderDevices(); } @@ -388,84 +373,51 @@ const LLVoiceDeviceList& LLVoiceClient::getRenderDevices() void LLVoiceClient::getParticipantList(std::set<LLUUID> &participants) { - if (mVoiceModule) - { - mVoiceModule->getParticipantList(participants); - } - else - { - participants = std::set<LLUUID>(); - } + LLWebRTCVoiceClient::getInstance()->getParticipantList(participants); + LLVivoxVoiceClient::getInstance()->getParticipantList(participants); } bool LLVoiceClient::isParticipant(const LLUUID &speaker_id) { - if(mVoiceModule) - { - return mVoiceModule->isParticipant(speaker_id); - } - return false; + return LLWebRTCVoiceClient::getInstance()->isParticipant(speaker_id) || LLVivoxVoiceClient::getInstance()->isParticipant(speaker_id); } //-------------------------------------------------- // text chat - BOOL LLVoiceClient::isSessionTextIMPossible(const LLUUID& id) { - if (mVoiceModule) + if (mSpatialVoiceModule) { - return mVoiceModule->isSessionTextIMPossible(id); + return mSpatialVoiceModule->isSessionTextIMPossible(id); } else { return FALSE; - } -} - -BOOL LLVoiceClient::isSessionCallBackPossible(const LLUUID& id) -{ - if (mVoiceModule) - { - return mVoiceModule->isSessionCallBackPossible(id); } - else - { - return FALSE; - } } -/* obsolete -BOOL LLVoiceClient::sendTextMessage(const LLUUID& participant_id, const std::string& message) +BOOL LLVoiceClient::isSessionCallBackPossible(const LLUUID& id) { - if (mVoiceModule) + if (mSpatialVoiceModule) { - return mVoiceModule->sendTextMessage(participant_id, message); + return mSpatialVoiceModule->isSessionCallBackPossible(id); } else { return FALSE; } } -*/ - -void LLVoiceClient::endUserIMSession(const LLUUID& participant_id) -{ - if (mVoiceModule) - { - // mVoiceModule->endUserIMSession(participant_id); // A SLim leftover - } -} //---------------------------------------------- // channels bool LLVoiceClient::inProximalChannel() { - if (mVoiceModule) + if (mSpatialVoiceModule) { - return mVoiceModule->inProximalChannel(); + return mSpatialVoiceModule->inProximalChannel(); } else { @@ -474,112 +426,111 @@ bool LLVoiceClient::inProximalChannel() } void LLVoiceClient::setNonSpatialChannel( - const std::string &uri, - const std::string &credentials, + const LLSD& channelInfo, bool hangup_on_last_leave) { - if (mVoiceModule) + setNonSpatialVoiceModule(channelInfo["voice_server_type"].asString()); + if (mSpatialVoiceModule) { - mVoiceModule->setNonSpatialChannel(uri, credentials, hangup_on_last_leave); + mSpatialVoiceModule->processChannels(false); } + if (mNonSpatialVoiceModule) + { + mNonSpatialVoiceModule->setNonSpatialChannel(channelInfo, hangup_on_last_leave); + mNonSpatialVoiceModule->processChannels(true); + } } -void LLVoiceClient::setSpatialChannel( - const std::string &uri, - const std::string &credentials) +void LLVoiceClient::setSpatialChannel(const LLSD &channelInfo) { - if (mVoiceModule) + LLViewerRegion *region = gAgent.getRegion(); + if (region && region->simulatorFeaturesReceived()) { - mVoiceModule->setSpatialChannel(uri, credentials); + LLSD simulatorFeatures; + region->getSimulatorFeatures(simulatorFeatures); + setSpatialVoiceModule(simulatorFeatures["VoiceServerType"].asString()); } -} - -void LLVoiceClient::leaveNonSpatialChannel() -{ - if (mVoiceModule) + if (mNonSpatialVoiceModule) { - mVoiceModule->leaveNonSpatialChannel(); + mNonSpatialVoiceModule->leaveNonSpatialChannel(); + mNonSpatialVoiceModule->processChannels(false); + mNonSpatialVoiceModule = nullptr; } -} - -void LLVoiceClient::leaveChannel(void) -{ - if (mVoiceModule) + if (mSpatialVoiceModule) { - mVoiceModule->leaveChannel(); + mSpatialVoiceModule->setSpatialChannel(channelInfo); + mSpatialVoiceModule->processChannels(true); } } -std::string LLVoiceClient::getCurrentChannel() +void LLVoiceClient::leaveNonSpatialChannel() { - if (mVoiceModule) - { - return mVoiceModule->getCurrentChannel(); - } - else + if (mNonSpatialVoiceModule) + { + mNonSpatialVoiceModule->leaveNonSpatialChannel(); + mNonSpatialVoiceModule->processChannels(false); + mNonSpatialVoiceModule = nullptr; + } + if (mSpatialVoiceModule) { - return std::string(); + mSpatialVoiceModule->processChannels(true); + ; } } - -//--------------------------------------- -// invitations - -bool LLVoiceClient::hasP2PInterface() +void LLVoiceClient::activateSpatialChannel(bool activate) { - if (mVoiceModule) - return mVoiceModule->hasP2PInterface(); - return false; + if (mSpatialVoiceModule) + { + mSpatialVoiceModule->processChannels(activate); + } } -void LLVoiceClient::callUser(const LLUUID &uuid) +bool LLVoiceClient::isCurrentChannel(const LLSD& channelInfo) { - if (mVoiceModule) mVoiceModule->callUser(uuid); + return LLWebRTCVoiceClient::getInstance()->isCurrentChannel(channelInfo) || + LLVivoxVoiceClient::getInstance()->isCurrentChannel(channelInfo); } -bool LLVoiceClient::isValidChannel(std::string &session_handle) +bool LLVoiceClient::compareChannels(const LLSD &channelInfo1, const LLSD &channelInfo2) { - if (mVoiceModule) - { - return mVoiceModule->isValidChannel(session_handle); - } - else - { - return false; - } + return LLWebRTCVoiceClient::getInstance()->compareChannels(channelInfo1, channelInfo2) || + LLVivoxVoiceClient::getInstance()->compareChannels(channelInfo1, channelInfo2); } -bool LLVoiceClient::answerInvite(std::string &channelHandle) +LLVoiceP2PIncomingCallInterfacePtr LLVoiceClient::getIncomingCallInterface(const LLSD& voice_call_info) { - if (mVoiceModule) - { - return mVoiceModule->answerInvite(channelHandle); - } - else + LLVoiceModuleInterface *module = getVoiceModule(voice_call_info["voice_server_type"]); + if (module) { - return false; + return module->getIncomingCallInterface(voice_call_info); } + return nullptr; + } -void LLVoiceClient::declineInvite(std::string &channelHandle) +//--------------------------------------- +// outgoing calls +LLVoiceP2POutgoingCallInterface *LLVoiceClient::getOutgoingCallInterface(const LLSD& voiceChannelInfo) { - if (mVoiceModule) mVoiceModule->declineInvite(channelHandle); + LLVoiceModuleInterface *module = getVoiceModule(voiceChannelInfo["voice_server_type"].asString()); + return dynamic_cast<LLVoiceP2POutgoingCallInterface *>(module); } - //------------------------------------------ // Volume/gain void LLVoiceClient::setVoiceVolume(F32 volume) { - if (mVoiceModule) mVoiceModule->setVoiceVolume(volume); + LLWebRTCVoiceClient::getInstance()->setVoiceVolume(volume); + LLVivoxVoiceClient::getInstance()->setVoiceVolume(volume); } -void LLVoiceClient::setMicGain(F32 volume) +void LLVoiceClient::setMicGain(F32 gain) { - if (mVoiceModule) mVoiceModule->setMicGain(volume); + LLWebRTCVoiceClient::getInstance()->setMicGain(gain); + LLVivoxVoiceClient::getInstance()->setMicGain(gain); } @@ -588,22 +539,13 @@ void LLVoiceClient::setMicGain(F32 volume) bool LLVoiceClient::voiceEnabled() { - if (mVoiceModule) - { - return mVoiceModule->voiceEnabled(); - } - else - { - return false; - } + return gSavedSettings.getBOOL("EnableVoiceChat") && !gSavedSettings.getBOOL("CmdLineDisableVoice") && !gNonInteractive; } void LLVoiceClient::setVoiceEnabled(bool enabled) { - if (mVoiceModule) - { - mVoiceModule->setVoiceEnabled(enabled); - } + LLWebRTCVoiceClient::getInstance()->setVoiceEnabled(enabled); + LLVivoxVoiceClient::getInstance()->setVoiceEnabled(enabled); } void LLVoiceClient::updateMicMuteLogic() @@ -622,25 +564,8 @@ void LLVoiceClient::updateMicMuteLogic() // Either of these always overrides any other PTT setting. new_mic_mute = true; } - - if (mVoiceModule) mVoiceModule->setMuteMic(new_mic_mute); -} - -void LLVoiceClient::setLipSyncEnabled(BOOL enabled) -{ - if (mVoiceModule) mVoiceModule->setLipSyncEnabled(enabled); -} - -BOOL LLVoiceClient::lipSyncEnabled() -{ - if (mVoiceModule) - { - return mVoiceModule->lipSyncEnabled(); - } - else - { - return false; - } + LLWebRTCVoiceClient::getInstance()->setMuteMic(new_mic_mute); + LLVivoxVoiceClient::getInstance()->setMuteMic(new_mic_mute); } void LLVoiceClient::setMuteMic(bool muted) @@ -726,9 +651,13 @@ void LLVoiceClient::toggleUserPTTState(void) BOOL LLVoiceClient::getVoiceEnabled(const LLUUID& id) { - if (mVoiceModule) + if (mNonSpatialVoiceModule) + { + return mNonSpatialVoiceModule->getVoiceEnabled(id); + } + else if (mSpatialVoiceModule) { - return mVoiceModule->getVoiceEnabled(id); + return mSpatialVoiceModule->getVoiceEnabled(id); } else { @@ -738,9 +667,13 @@ BOOL LLVoiceClient::getVoiceEnabled(const LLUUID& id) std::string LLVoiceClient::getDisplayName(const LLUUID& id) { - if (mVoiceModule) + if (mNonSpatialVoiceModule) + { + return mNonSpatialVoiceModule->getDisplayName(id); + } + else if (mSpatialVoiceModule) { - return mVoiceModule->getDisplayName(id); + return mSpatialVoiceModule->getDisplayName(id); } else { @@ -750,47 +683,35 @@ std::string LLVoiceClient::getDisplayName(const LLUUID& id) bool LLVoiceClient::isVoiceWorking() const { - if (mVoiceModule) - { - return mVoiceModule->isVoiceWorking(); - } - return false; + return LLVivoxVoiceClient::getInstance()->isVoiceWorking() || LLWebRTCVoiceClient::getInstance()->isVoiceWorking(); } BOOL LLVoiceClient::isParticipantAvatar(const LLUUID& id) { - if (mVoiceModule) - { - return mVoiceModule->isParticipantAvatar(id); - } - else - { - return FALSE; - } + return TRUE; } BOOL LLVoiceClient::isOnlineSIP(const LLUUID& id) { - return FALSE; + return FALSE; } BOOL LLVoiceClient::getIsSpeaking(const LLUUID& id) { - if (mVoiceModule) - { - return mVoiceModule->getIsSpeaking(id); - } - else - { - return FALSE; - } + return LLVivoxVoiceClient::getInstance()->getIsSpeaking(id) || LLWebRTCVoiceClient::getInstance()->getIsSpeaking(id); } BOOL LLVoiceClient::getIsModeratorMuted(const LLUUID& id) { - if (mVoiceModule) + // don't bother worrying about p2p calls, as + // p2p calls don't have mute. + if (mNonSpatialVoiceModule) + { + return mNonSpatialVoiceModule->getIsModeratorMuted(id); + } + else if (mSpatialVoiceModule) { - return mVoiceModule->getIsModeratorMuted(id); + return mSpatialVoiceModule->getIsModeratorMuted(id); } else { @@ -799,22 +720,21 @@ BOOL LLVoiceClient::getIsModeratorMuted(const LLUUID& id) } F32 LLVoiceClient::getCurrentPower(const LLUUID& id) -{ - if (mVoiceModule) - { - return mVoiceModule->getCurrentPower(id); - } - else - { - return 0.0; - } +{ + return std::fmax(LLVivoxVoiceClient::getInstance()->getCurrentPower(id), LLWebRTCVoiceClient::getInstance()->getCurrentPower(id)); } BOOL LLVoiceClient::getOnMuteList(const LLUUID& id) { - if (mVoiceModule) + // don't bother worrying about p2p calls, as + // p2p calls don't have mute. + if (mNonSpatialVoiceModule) + { + return mNonSpatialVoiceModule->getOnMuteList(id); + } + else if (mSpatialVoiceModule) { - return mVoiceModule->getOnMuteList(id); + return mSpatialVoiceModule->getOnMuteList(id); } else { @@ -824,19 +744,13 @@ BOOL LLVoiceClient::getOnMuteList(const LLUUID& id) F32 LLVoiceClient::getUserVolume(const LLUUID& id) { - if (mVoiceModule) - { - return mVoiceModule->getUserVolume(id); - } - else - { - return 0.0; - } + return std::fmax(LLVivoxVoiceClient::getInstance()->getUserVolume(id), LLWebRTCVoiceClient::getInstance()->getUserVolume(id)); } void LLVoiceClient::setUserVolume(const LLUUID& id, F32 volume) { - if (mVoiceModule) mVoiceModule->setUserVolume(id, volume); + LLWebRTCVoiceClient::getInstance()->setUserVolume(id, volume); + LLVivoxVoiceClient::getInstance()->setUserVolume(id, volume); } //-------------------------------------------------- @@ -844,48 +758,49 @@ void LLVoiceClient::setUserVolume(const LLUUID& id, F32 volume) void LLVoiceClient::addObserver(LLVoiceClientStatusObserver* observer) { - if (mVoiceModule) mVoiceModule->addObserver(observer); + LLVivoxVoiceClient::getInstance()->addObserver(observer); + LLWebRTCVoiceClient::getInstance()->addObserver(observer); } void LLVoiceClient::removeObserver(LLVoiceClientStatusObserver* observer) { - if (mVoiceModule) - { - mVoiceModule->removeObserver(observer); - } + LLVivoxVoiceClient::getInstance()->removeObserver(observer); + LLWebRTCVoiceClient::getInstance()->removeObserver(observer); } void LLVoiceClient::addObserver(LLFriendObserver* observer) { - if (mVoiceModule) mVoiceModule->addObserver(observer); + LLVivoxVoiceClient::getInstance()->addObserver(observer); + LLWebRTCVoiceClient::getInstance()->addObserver(observer); } void LLVoiceClient::removeObserver(LLFriendObserver* observer) { - if (mVoiceModule) - { - mVoiceModule->removeObserver(observer); - } + LLVivoxVoiceClient::getInstance()->removeObserver(observer); + LLWebRTCVoiceClient::getInstance()->removeObserver(observer); } void LLVoiceClient::addObserver(LLVoiceClientParticipantObserver* observer) { - if (mVoiceModule) mVoiceModule->addObserver(observer); + LLVivoxVoiceClient::getInstance()->addObserver(observer); + LLWebRTCVoiceClient::getInstance()->addObserver(observer); } void LLVoiceClient::removeObserver(LLVoiceClientParticipantObserver* observer) { - if (mVoiceModule) - { - mVoiceModule->removeObserver(observer); - } + LLVivoxVoiceClient::getInstance()->removeObserver(observer); + LLWebRTCVoiceClient::getInstance()->removeObserver(observer); } std::string LLVoiceClient::sipURIFromID(const LLUUID &id) { - if (mVoiceModule) + if (mNonSpatialVoiceModule) { - return mVoiceModule->sipURIFromID(id); + return mNonSpatialVoiceModule->sipURIFromID(id); + } + else if (mSpatialVoiceModule) + { + return mSpatialVoiceModule->sipURIFromID(id); } else { @@ -895,7 +810,7 @@ std::string LLVoiceClient::sipURIFromID(const LLUUID &id) LLVoiceEffectInterface* LLVoiceClient::getVoiceEffectInterface() const { - return getVoiceEffectEnabled() ? dynamic_cast<LLVoiceEffectInterface*>(mVoiceModule) : NULL; + return getVoiceEffectEnabled() ? dynamic_cast<LLVoiceEffectInterface*>(mSpatialVoiceModule) : NULL; } /////////////////// @@ -983,22 +898,8 @@ class LLViewerParcelVoiceInfo : public LLHTTPNode //local parcel id to make sure it's for the same parcel //we believe we're in if ( body.has("voice_credentials") ) - { - LLSD voice_credentials = body["voice_credentials"]; - std::string uri; - std::string credentials; - - if ( voice_credentials.has("channel_uri") ) - { - uri = voice_credentials["channel_uri"].asString(); - } - if ( voice_credentials.has("channel_credentials") ) - { - credentials = - voice_credentials["channel_credentials"].asString(); - } - - LLVoiceClient::getInstance()->setSpatialChannel(uri, credentials); + { + LLVoiceClient::getInstance()->setSpatialChannel(body["voice_credentials"]); } } } diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h index 4ed3cd5066..87b6469783 100644 --- a/indra/newview/llvoiceclient.h +++ b/indra/newview/llvoiceclient.h @@ -38,6 +38,7 @@ class LLVOAvatar; #include "llcallingcard.h" // for LLFriendObserver #include "llsecapi.h" #include "llcontrol.h" +#include <boost/shared_ptr.hpp> // devices @@ -87,7 +88,7 @@ public: } EStatusType; virtual ~LLVoiceClientStatusObserver() { } - virtual void onChange(EStatusType status, const std::string &channelURI, bool proximal) = 0; + virtual void onChange(EStatusType status, const LLSD& channelInfo, bool proximal) = 0; static std::string status2string(EStatusType inStatus); }; @@ -95,6 +96,7 @@ public: struct LLVoiceVersionInfo { std::string voiceServerType; + std::string internalVoiceServerType; int majorVersion; int minorVersion; std::string serverVersion; @@ -102,6 +104,38 @@ struct LLVoiceVersionInfo }; ////////////////////////////////// +/// @class LLVoiceP2POutgoingCallInterface +/// @brief Outgoing call interface +/// +/// For providers that support P2P signaling (vivox) +///////////////////////////////// + +class LLVoiceP2POutgoingCallInterface +{ + public: + // initiate an outgoing call to a user + virtual void callUser(const LLUUID &agentID) = 0; + virtual void hangup() = 0; +}; + +////////////////////////////////// +/// @class LLVoiceP2PIncomingCallInterface +/// @brief Incoming call interface +/// +/// For providers that support P2P signaling (vivox) +///////////////////////////////// +class LLVoiceP2PIncomingCallInterface +{ + public: + virtual ~LLVoiceP2PIncomingCallInterface() {} + + virtual bool answerInvite() = 0; + virtual void declineInvite() = 0; +}; + +typedef boost::shared_ptr<LLVoiceP2PIncomingCallInterface> LLVoiceP2PIncomingCallInterfacePtr; + +////////////////////////////////// /// @class LLVoiceModuleInterface /// @brief Voice module interface /// @@ -170,32 +204,31 @@ public: // Note that gestures should only fire if this returns true. virtual bool inProximalChannel()=0; - virtual void setNonSpatialChannel(const std::string &uri, - const std::string &credentials, + virtual void setNonSpatialChannel(const LLSD& channelInfo, bool hangup_on_last_leave = false)=0; - virtual bool setSpatialChannel(const std::string &uri, - const std::string &credentials)=0; - - virtual void leaveNonSpatialChannel()=0; + virtual bool setSpatialChannel(const LLSD& channelInfo)=0; - virtual void leaveChannel(void)=0; - - // Returns the URI of the current channel, or an empty string if not currently in a channel. - // NOTE that it will return an empty string if it's in the process of joining a channel. - virtual std::string getCurrentChannel()=0; + virtual void leaveNonSpatialChannel() = 0; + virtual void processChannels(bool process) = 0; + + virtual bool isCurrentChannel(const LLSD &channelInfo) = 0; + virtual bool compareChannels(const LLSD &channelInfo1, const LLSD &channelInfo2) = 0; + //@} ////////////////////////// - /// @name invitations + /// @name p2p //@{ - // start a voice channel with the specified user - virtual bool hasP2PInterface()=0; - virtual void callUser(const LLUUID &uuid)=0; - virtual bool isValidChannel(std::string& channelHandle)=0; - virtual bool answerInvite(std::string &channelHandle)=0; - virtual void declineInvite(std::string &channelHandle)=0; + + // 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 + virtual LLVoiceP2POutgoingCallInterface* getOutgoingCallInterface() = 0; + + // an incoming call was received, and the incoming call dialogue is asking for an interface to + // answer or decline. + virtual LLVoiceP2PIncomingCallInterfacePtr getIncomingCallInterface(const LLSD &voice_call_info) = 0; //@} ///////////////////////// @@ -208,10 +241,7 @@ public: ///////////////////////// /// @name enable disable voice and features //@{ - virtual bool voiceEnabled()=0; virtual void setVoiceEnabled(bool enabled)=0; - virtual void setLipSyncEnabled(BOOL enabled)=0; - virtual BOOL lipSyncEnabled()=0; virtual void setMuteMic(bool muted)=0; // Set the mute state of the local mic. //@} @@ -235,7 +265,6 @@ public: virtual BOOL isSessionTextIMPossible(const LLUUID& id)=0; virtual BOOL isSessionCallBackPossible(const LLUUID& id)=0; //virtual BOOL sendTextMessage(const LLUUID& participant_id, const std::string& message)=0; - virtual void endUserIMSession(const LLUUID &uuid)=0; //@} // authorize the user @@ -377,27 +406,24 @@ public: // Note that gestures should only fire if this returns true. bool inProximalChannel(); - void setNonSpatialChannel( - const std::string &uri, - const std::string &credentials, - bool hangup_on_last_leave = false); + void setNonSpatialChannel(const LLSD& channelInfo, + bool hangup_on_last_leave = false); + + void setSpatialChannel(const LLSD &channelInfo); + + void activateSpatialChannel(bool activate); - void setSpatialChannel( - const std::string &uri, - const std::string &credentials); void leaveNonSpatialChannel(); - - // Returns the URI of the current channel, or an empty string if not currently in a channel. - // NOTE that it will return an empty string if it's in the process of joining a channel. - std::string getCurrentChannel(); - // start a voice channel with the specified user - bool hasP2PInterface(); // true - can use the following. false - use conference/ad-hoc instead - void callUser(const LLUUID &uuid); - bool isValidChannel(std::string& channelHandle); - bool answerInvite(std::string &channelHandle); - void declineInvite(std::string &channelHandle); - void leaveChannel(void); // call this on logout or teleport begin - + + bool isCurrentChannel(const LLSD& channelInfo); + + bool compareChannels(const LLSD& channelInfo1, const LLSD& channelInfo2); + + // 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); + + LLVoiceP2PIncomingCallInterfacePtr getIncomingCallInterface(const LLSD &voiceCallInfo); ///////////////////////////// // Sending updates of current state @@ -407,7 +433,6 @@ public: void setMicGain(F32 volume); void setUserVolume(const LLUUID& id, F32 volume); // set's volume for specified agent, from 0-1 (where .5 is nominal) bool voiceEnabled(); - void setLipSyncEnabled(BOOL enabled); void setMuteMic(bool muted); // Use this to mute the local mic (for when the client is minimized, etc), ignoring user PTT state. void setUserPTTState(bool ptt); bool getUserPTTState(); @@ -421,8 +446,6 @@ public: void updateMicMuteLogic(); - BOOL lipSyncEnabled(); - boost::signals2::connection MicroChangedCallback(const micro_changed_signal_t::slot_type& cb ) { return mMicroChangedSignal.connect(cb); } @@ -450,10 +473,10 @@ public: BOOL isSessionTextIMPossible(const LLUUID& id); BOOL isSessionCallBackPossible(const LLUUID& id); //BOOL sendTextMessage(const LLUUID& participant_id, const std::string& message) const {return true;} ; - void endUserIMSession(const LLUUID &uuid); //@} - void setVoiceModule(const std::string& voice_server_type); + void setSpatialVoiceModule(const std::string& voice_server_type); + void setNonSpatialVoiceModule(const std::string &voice_server_type); void userAuthorized(const std::string& user_id, const LLUUID &agentID); @@ -483,11 +506,10 @@ private: void init(LLPumpIO *pump); protected: - LLVoiceModuleInterface* mVoiceModule; + LLVoiceModuleInterface* mSpatialVoiceModule; + LLVoiceModuleInterface* mNonSpatialVoiceModule; LLPumpIO *m_servicePump; - std::string mUserID; - LLUUID mAgentID; boost::signals2::connection mSimulatorFeaturesReceivedSlot; LLCachedControl<bool> mVoiceEffectEnabled; diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index e003dc3317..4562dd89fc 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -80,13 +80,14 @@ extern LLMenuBarGL* gMenuBarView; extern void handle_voice_morphing_subscribe(); +const std::string VIVOX_VOICE_SERVER_TYPE = "vivox"; + namespace { const F32 VOLUME_SCALE_VIVOX = 0.01f; const F32 SPEAKING_TIMEOUT = 1.f; static const std::string VISIBLE_VOICE_SERVER_TYPE = "Vivox"; - static const std::string VIVOX_VOICE_SERVER_TYPE = "vivox"; // Don't retry connecting to the daemon more frequently than this: const F32 DAEMON_CONNECT_THROTTLE_SECONDS = 1.0f; @@ -326,10 +327,9 @@ LLVivoxVoiceClient::LLVivoxVoiceClient() : mMicVolumeDirty(true), mVoiceEnabled(false), + mProcessChannels(false), mWriteInProgress(false), - mLipSyncEnabled(false), - mVoiceFontsReceived(false), mVoiceFontsNew(false), mVoiceFontListDirty(false), @@ -360,6 +360,7 @@ LLVivoxVoiceClient::LLVivoxVoiceClient() : mVoiceVersion.serverVersion = ""; mVoiceVersion.voiceServerType = VISIBLE_VOICE_SERVER_TYPE; + mVoiceVersion.internalVoiceServerType = VIVOX_VOICE_SERVER_TYPE; mVoiceVersion.majorVersion = 1; mVoiceVersion.minorVersion = 0; mVoiceVersion.mBuildVersion = ""; @@ -460,7 +461,7 @@ const LLVoiceVersionInfo& LLVivoxVoiceClient::getVersion() void LLVivoxVoiceClient::updateSettings() { - setVoiceEnabled(voiceEnabled()); + setVoiceEnabled(LLVoiceClient::getInstance()->voiceEnabled()); setEarLocation(gSavedSettings.getS32("VoiceEarLocation")); std::string inputDevice = gSavedSettings.getString("VoiceInputAudioDevice"); @@ -469,7 +470,6 @@ void LLVivoxVoiceClient::updateSettings() setRenderDevice(outputDevice); F32 mic_level = gSavedSettings.getF32("AudioLevelMic"); setMicGain(mic_level); - setLipSyncEnabled(gSavedSettings.getBOOL("LipSyncEnabled")); } ///////////////////////////// @@ -742,19 +742,6 @@ void LLVivoxVoiceClient::voiceControlStateMachine(S32 &coro_state) return; } - - // grab the active voice server version info to see if we should use - // vivox. - LLVoiceVersionInfo version = LLVoiceClient::getInstance()->getVersion(); - if (version.voiceServerType != VISIBLE_VOICE_SERVER_TYPE) - { - // we've switched to another voice provider, so - // disable voice and shut down vivox. Don't - // notify, though. - mVoiceEnabled = false; - } - - switch (coro_state) { case VOICE_STATE_TP_WAIT: @@ -932,7 +919,7 @@ bool LLVivoxVoiceClient::callbackEndDaemon(const LLSD& data) bool LLVivoxVoiceClient::startAndLaunchDaemon() { //--------------------------------------------------------------------- - if (!voiceEnabled()) + if (!LLVoiceClient::getInstance()->voiceEnabled()) { // Voice is locked out, we must not launch the vivox daemon. LL_WARNS("Voice") << "voice disabled; not starting daemon" << LL_ENDL; @@ -1212,7 +1199,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; std::string voiceSipUriHostname; std::string voiceAccountServerUri; std::string voiceUserName = result["username"].asString(); @@ -1608,48 +1595,7 @@ bool LLVivoxVoiceClient::requestParcelVoiceInfo() return false; } - std::string uri; - std::string credentials; - - if (result.has("voice_credentials")) - { - LLSD voice_credentials = result["voice_credentials"]; - if (voice_credentials.has("channel_uri")) - { - LL_DEBUGS("Voice") << "got voice channel uri" << LL_ENDL; - uri = voice_credentials["channel_uri"].asString(); - } - else - { - LL_WARNS("Voice") << "No voice channel uri" << LL_ENDL; - } - - if (voice_credentials.has("channel_credentials")) - { - LL_DEBUGS("Voice") << "got voice channel credentials" << LL_ENDL; - credentials = - voice_credentials["channel_credentials"].asString(); - } - else - { - LLVoiceChannel* channel = LLVoiceChannel::getCurrentVoiceChannel(); - if (channel != NULL) - { - if (channel->getSessionName().empty() && channel->getSessionID().isNull()) - { - if (LLViewerParcelMgr::getInstance()->allowAgentVoice()) - { - LL_WARNS("Voice") << "No channel credentials for default channel" << LL_ENDL; - } - } - else - { - LL_WARNS("Voice") << "No voice channel credentials" << LL_ENDL; - } - } - } - } - else + if (!result.has("voice_credentials")) { if (LLViewerParcelMgr::getInstance()->allowAgentVoice()) { @@ -1663,7 +1609,7 @@ bool LLVivoxVoiceClient::requestParcelVoiceInfo() // set the spatial channel. If no voice credentials or uri are // available, then we simply drop out of voice spatially. - return !setSpatialChannel(uri, credentials); + return setSpatialChannel(result["voice_credentials"]); } bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession) @@ -1990,17 +1936,6 @@ bool LLVivoxVoiceClient::waitForChannel() return false; } - // grab the active voice server version info to see if we should use - // vivox. - LLVoiceVersionInfo version = LLVoiceClient::getInstance()->getVersion(); - if (version.voiceServerType != VISIBLE_VOICE_SERVER_TYPE) - { - // we've switched to another voice provider, so - // disable voice and shut down vivox. Don't - // notify, though. - mVoiceEnabled = false; - } - switch (state) { case VOICE_CHANNEL_STATE_LOGIN: @@ -2037,7 +1972,6 @@ bool LLVivoxVoiceClient::waitForChannel() break; case VOICE_CHANNEL_STATE_START_CHANNEL_PROCESSING: - mIsProcessingChannels = true; llcoro::suspend(); state = VOICE_CHANNEL_STATE_PROCESS_CHANNEL; break; @@ -2051,7 +1985,7 @@ bool LLVivoxVoiceClient::waitForChannel() { recordingAndPlaybackMode(); } - else if (checkParcelChanged() || (mNextAudioSession == NULL)) + else if (mProcessChannels && (mNextAudioSession == NULL) && checkParcelChanged()) { // the parcel is changed, or we have no pending audio sessions, // so try to request the parcel voice info @@ -2066,15 +2000,23 @@ bool LLVivoxVoiceClient::waitForChannel() } else if (mNextAudioSession) { + if (!mNextAudioSession->mIsP2P && !mProcessChannels) + { + llcoro::suspend(); + break; + } sessionStatePtr_t joinSession = mNextAudioSession; mNextAudioSession.reset(); + mIsProcessingChannels = true; if (!runSession(joinSession)) //suspends { + mIsProcessingChannels = false; LL_DEBUGS("Voice") << "runSession returned false; leaving inner loop" << LL_ENDL; break; } else { + mIsProcessingChannels = false; LL_DEBUGS("Voice") << "runSession returned true to inner loop" << " RelogRequested=" << mRelogRequested @@ -2190,6 +2132,7 @@ bool LLVivoxVoiceClient::runSession(const sessionStatePtr_t &session) mIsInChannel = true; mMuteMicDirty = true; + mSessionTerminateRequested = false; while (!sShuttingDown && mVoiceEnabled @@ -2447,95 +2390,11 @@ int LLVivoxVoiceClient::voicePlaybackBuffer() bool LLVivoxVoiceClient::performMicTuning() { LL_INFOS("Voice") << "Entering voice tuning mode." << LL_ENDL; - mIsInTuningMode = true; - llcoro::suspend(); while (mTuningMode && !sShuttingDown) { - - if (mCaptureDeviceDirty || mRenderDeviceDirty) - { - // These can't be changed while in tuning mode. Set them before starting. - std::ostringstream stream; - - buildSetCaptureDevice(stream); - buildSetRenderDevice(stream); - - if (!stream.str().empty()) - { - writeString(stream.str()); - } - - llcoro::suspendUntilTimeout(UPDATE_THROTTLE_SECONDS); - } - - // loop mic back to render device. - //setMuteMic(0); // make sure the mic is not muted - std::ostringstream stream; - - stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Connector.MuteLocalMic.1\">" - << "<ConnectorHandle>" << LLVivoxSecurity::getInstance()->connectorHandle() << "</ConnectorHandle>" - << "<Value>false</Value>" - << "</Request>\n\n\n"; - - // Dirty the mute mic state so that it will get reset when we finishing previewing - mMuteMicDirty = true; - mTuningSpeakerVolumeDirty = true; - - writeString(stream.str()); - tuningCaptureStartSendMessage(1); // 1-loop, zero, don't loop - - //--------------------------------------------------------------------- - if (!sShuttingDown) - { - llcoro::suspend(); - } - - while (mTuningMode && !mCaptureDeviceDirty && !mRenderDeviceDirty && !sShuttingDown) - { - // process mic/speaker volume changes - if (mTuningMicVolumeDirty || mTuningSpeakerVolumeDirty) - { - std::ostringstream stream; - - if (mTuningMicVolumeDirty) - { - LL_INFOS("Voice") << "setting tuning mic level to " << mTuningMicVolume << LL_ENDL; - stream - << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Aux.SetMicLevel.1\">" - << "<Level>" << mTuningMicVolume << "</Level>" - << "</Request>\n\n\n"; - } - - if (mTuningSpeakerVolumeDirty) - { - LL_INFOS("Voice") << "setting tuning speaker level to " << mTuningSpeakerVolume << LL_ENDL; - stream - << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Aux.SetSpeakerLevel.1\">" - << "<Level>" << mTuningSpeakerVolume << "</Level>" - << "</Request>\n\n\n"; - } - - mTuningMicVolumeDirty = false; - mTuningSpeakerVolumeDirty = false; - - if (!stream.str().empty()) - { - writeString(stream.str()); - } - } - llcoro::suspend(); - } - - //--------------------------------------------------------------------- - - // transition out of mic tuning - tuningCaptureStopSendMessage(); - if ((mCaptureDeviceDirty || mRenderDeviceDirty) && !sShuttingDown) - { - llcoro::suspendUntilTimeout(UPDATE_THROTTLE_SECONDS); - } + llcoro::suspendUntilTimeout(UPDATE_THROTTLE_SECONDS); } mIsInTuningMode = false; @@ -2661,6 +2520,7 @@ void LLVivoxVoiceClient::sessionCreateSendMessage(const sessionStatePtr_t &sessi << "<VoiceFontID>" << font_index << "</VoiceFontID>" << "<Name>" << mChannelName << "</Name>" << "</Request>\n\n\n"; + LL_WARNS("Voice") << "Session.Create: " << stream.str() << LL_ENDL; writeString(stream.str()); } @@ -2960,6 +2820,9 @@ void LLVivoxVoiceClient::tuningStart() void LLVivoxVoiceClient::tuningStop() { mTuningMode = false; + // force a renegotiation. + mCurrentParcelLocalID = 0; + mCurrentRegionName = ""; } bool LLVivoxVoiceClient::inTuningMode() @@ -4961,8 +4824,10 @@ bool LLVivoxVoiceClient::switchChannel( // If a terminate has been requested, we need to compare against where the URI we're already headed to. if(mNextAudioSession) { - if(mNextAudioSession->mSIPURI != uri) + if (mNextAudioSession->mSIPURI != uri) + { needsSwitch = true; + } } else { @@ -5052,23 +4917,19 @@ void LLVivoxVoiceClient::joinSession(const sessionStatePtr_t &session) } } -void LLVivoxVoiceClient::setNonSpatialChannel( - const std::string &uri, - const std::string &credentials, - bool hangup_on_last_leave) +void LLVivoxVoiceClient::setNonSpatialChannel(const LLSD& channelInfo, bool hangup_on_last_leave) { - switchChannel(uri, false, false, false, credentials); + switchChannel(channelInfo["channel_uri"].asString(), false, false, false, channelInfo["channel_credentials"].asString()); } -bool LLVivoxVoiceClient::setSpatialChannel( - const std::string &uri, - const std::string &credentials) +bool LLVivoxVoiceClient::setSpatialChannel(const LLSD& channelInfo) { - mSpatialSessionURI = uri; - mSpatialSessionCredentials = credentials; + mProcessChannels = true; + mSpatialSessionURI = channelInfo["channel_uri"].asString(); + mSpatialSessionCredentials = channelInfo["channel_credentials"].asString(); mAreaVoiceDisabled = mSpatialSessionURI.empty(); - LL_DEBUGS("Voice") << "got spatial channel uri: \"" << uri << "\"" << LL_ENDL; + LL_DEBUGS("Voice") << "got spatial channel uri: \"" << mSpatialSessionURI << "\"" << LL_ENDL; if((mIsInChannel && mAudioSession && !(mAudioSession->mIsSpatial)) || (mNextAudioSession && !(mNextAudioSession->mIsSpatial))) { @@ -5089,85 +4950,39 @@ void LLVivoxVoiceClient::callUser(const LLUUID &uuid) switchChannel(userURI, false, true, true); } -#if 0 -// Vivox text IMs are not in use. -LLVivoxVoiceClient::sessionStatePtr_t LLVivoxVoiceClient::startUserIMSession(const LLUUID &uuid) -{ - // Figure out if a session with the user already exists - sessionStatePtr_t session(findSession(uuid)); - if(!session) - { - // No session with user, need to start one. - std::string uri = sipURIFromID(uuid); - session = addSession(uri); - - llassert(session); - if (!session) - return session; +void LLVivoxVoiceClient::hangup() { leaveChannel(); } - session->mIsSpatial = false; - session->mReconnect = false; - session->mIsP2P = true; - session->mCallerID = uuid; - } - - if(session->mHandle.empty()) - { - // Session isn't active -- start it up. - sessionCreateSendMessage(session, false, false); - } - else - { - // Session is already active -- start up text. - sessionTextConnectSendMessage(session); - } - - return session; -} -#endif -void LLVivoxVoiceClient::endUserIMSession(const LLUUID &uuid) +LLVoiceP2PIncomingCallInterfacePtr LLVivoxVoiceClient::getIncomingCallInterface(const LLSD &voice_call_info) { -#if 0 - // Vivox text IMs are not in use. - - // Figure out if a session with the user exists - sessionStatePtr_t session(findSession(uuid)); - if(session) - { - // found the session - if(!session->mHandle.empty()) - { - // sessionTextDisconnectSendMessage(session); // a SLim leftover, not used any more. - } - } - else - { - LL_DEBUGS("Voice") << "Session not found for participant ID " << uuid << LL_ENDL; - } -#endif + return boost::make_shared<LLVivoxVoiceP2PIncomingCall>(voice_call_info); } -bool LLVivoxVoiceClient::isValidChannel(std::string &sessionHandle) + +bool LLVivoxVoiceClient::answerInvite(const std::string &sessionHandle) { - return(findSession(sessionHandle) != NULL); - + // this is only ever used to answer incoming p2p call invites. + + sessionStatePtr_t session(findSession(sessionHandle)); + if (session) + { + session->mIsSpatial = false; + session->mReconnect = false; + session->mIsP2P = true; + + joinSession(session); + return true; + } + + return false; } -bool LLVivoxVoiceClient::answerInvite(std::string &sessionHandle) + +void LLVivoxVoiceClient::declineInvite(const std::string &sessionHandle) { - // this is only ever used to answer incoming p2p call invites. - sessionStatePtr_t session(findSession(sessionHandle)); - if(session) - { - session->mIsSpatial = false; - session->mReconnect = false; - session->mIsP2P = true; - - joinSession(session); - return true; - } - - return false; + if (session) + { + sessionMediaDisconnectSendMessage(session); + } } bool LLVivoxVoiceClient::isVoiceWorking() const @@ -5238,21 +5053,11 @@ BOOL LLVivoxVoiceClient::isSessionTextIMPossible(const LLUUID &session_id) return result; } - - -void LLVivoxVoiceClient::declineInvite(std::string &sessionHandle) -{ - sessionStatePtr_t session(findSession(sessionHandle)); - if(session) - { - sessionMediaDisconnectSendMessage(session); - } -} void LLVivoxVoiceClient::leaveNonSpatialChannel() { LL_DEBUGS("Voice") << "Request to leave spacial channel." << LL_ENDL; - + // Make sure we don't rejoin the current session. sessionStatePtr_t oldNextSession(mNextAudioSession); mNextAudioSession.reset(); @@ -5265,16 +5070,31 @@ void LLVivoxVoiceClient::leaveNonSpatialChannel() sessionTerminate(); } -std::string LLVivoxVoiceClient::getCurrentChannel() +void LLVivoxVoiceClient::processChannels(bool process) { - std::string result; - - if (mIsInChannel && !mSessionTerminateRequested) - { - result = getAudioSessionURI(); - } - - return result; + mProcessChannels = process; +} + +bool LLVivoxVoiceClient::isCurrentChannel(const LLSD &channelInfo) +{ + if (channelInfo["voice_server_type"].asString() != VIVOX_VOICE_SERVER_TYPE) + return false; + if (mAudioSession) + { + if (!channelInfo["sessionHandle"].asString().empty()) + { + return mAudioSession->mHandle == channelInfo["session_handle"].asString(); + } + return channelInfo["channel_uri"].asString() == mAudioSession->mSIPURI; + } + return false; +} + +bool LLVivoxVoiceClient::compareChannels(const LLSD& channelInfo1, const LLSD& channelInfo2) +{ + return (channelInfo1["voice_server_type"] == VIVOX_VOICE_SERVER_TYPE) && + (channelInfo1["voice_server_type"] == channelInfo2["voice_server_type"]) && + (channelInfo1["channel_uri"] == channelInfo2["channel_uri"]); } bool LLVivoxVoiceClient::inProximalChannel() @@ -5314,16 +5134,6 @@ std::string LLVivoxVoiceClient::sipURIFromAvatar(LLVOAvatar *avatar) return result; } -std::string LLVivoxVoiceClient::nameFromAvatar(LLVOAvatar *avatar) -{ - std::string result; - if(avatar) - { - result = nameFromID(avatar->getID()); - } - return result; -} - std::string LLVivoxVoiceClient::nameFromID(const LLUUID &uuid) { std::string result; @@ -5398,11 +5208,6 @@ bool LLVivoxVoiceClient::IDFromName(const std::string inName, LLUUID &uuid) return result; } -std::string LLVivoxVoiceClient::displayNameFromAvatar(LLVOAvatar *avatar) -{ - return avatar->getFullname(); -} - std::string LLVivoxVoiceClient::sipURIFromName(std::string &name) { std::string result; @@ -5443,12 +5248,15 @@ bool LLVivoxVoiceClient::inSpatialChannel(void) return result; } -std::string LLVivoxVoiceClient::getAudioSessionURI() + +LLSD LLVivoxVoiceClient::getAudioSessionChannelInfo() { - std::string result; + LLSD result; - if(mAudioSession) - result = mAudioSession->mSIPURI; + if (mAudioSession) + { + result = mAudioSession->getVoiceChannelInfo(); + } return result; } @@ -5650,31 +5458,6 @@ void LLVivoxVoiceClient::setVoiceEnabled(bool enabled) } } -bool LLVivoxVoiceClient::voiceEnabled() -{ - return gSavedSettings.getBOOL("EnableVoiceChat") && - !gSavedSettings.getBOOL("CmdLineDisableVoice") && - !gNonInteractive; -} - -void LLVivoxVoiceClient::setLipSyncEnabled(BOOL enabled) -{ - mLipSyncEnabled = enabled; -} - -BOOL LLVivoxVoiceClient::lipSyncEnabled() -{ - - if ( mVoiceEnabled ) - { - return mLipSyncEnabled; - } - else - { - return FALSE; - } -} - void LLVivoxVoiceClient::setEarLocation(S32 loc) { @@ -6005,6 +5788,18 @@ LLVivoxVoiceClient::sessionState::sessionState() : { } +LLSD LLVivoxVoiceClient::sessionState::getVoiceChannelInfo() +{ + LLSD result; + + result["voice_server_type"] = VIVOX_VOICE_SERVER_TYPE; + result["channel_credentials"] = mHash; + result["channel_uri"] = mSIPURI; + result["session_handle"] = mHandle; + + return result; +} + /*static*/ LLVivoxVoiceClient::sessionState::ptr_t LLVivoxVoiceClient::sessionState::createSession() { @@ -6451,7 +6246,7 @@ void LLVivoxVoiceClient::notifyStatusObservers(LLVoiceClientStatusObserver::ESta LL_DEBUGS("Voice") << " " << LLVoiceClientStatusObserver::status2string(status) - << ", session URI " << getAudioSessionURI() + << ", session channelInfo " << getAudioSessionChannelInfo() << ", proximal is " << inSpatialChannel() << LL_ENDL; @@ -6460,7 +6255,7 @@ void LLVivoxVoiceClient::notifyStatusObservers(LLVoiceClientStatusObserver::ESta ) { LLVoiceClientStatusObserver* observer = *it; - observer->onChange(status, getAudioSessionURI(), inSpatialChannel()); + observer->onChange(status, getAudioSessionChannelInfo(), inSpatialChannel()); // In case onError() deleted an entry. it = mStatusObservers.upper_bound(observer); } @@ -6472,6 +6267,7 @@ void LLVivoxVoiceClient::notifyStatusObservers(LLVoiceClientStatusObserver::ESta { bool voice_status = LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking(); + LL_WARNS("Voice") << "Setting voice connected " << (voice_status ? "True" : "False") << LL_ENDL; gAgent.setVoiceConnected(voice_status); if (voice_status) @@ -6546,7 +6342,6 @@ void LLVivoxVoiceClient::predAvatarNameResolution(const LLVivoxVoiceClient::sess if (session->mVoiceInvitePending) { session->mVoiceInvitePending = false; - LLIMMgr::getInstance()->inviteToSession( session->mIMSessionID, session->mName, @@ -6554,10 +6349,8 @@ void LLVivoxVoiceClient::predAvatarNameResolution(const LLVivoxVoiceClient::sess session->mName, IM_SESSION_P2P_INVITE, LLIMMgr::INVITATION_TYPE_VOICE, - session->mHandle, - session->mSIPURI); + session->getVoiceChannelInfo()); } - } } @@ -8111,3 +7904,7 @@ LLVivoxSecurity::LLVivoxSecurity() LLVivoxSecurity::~LLVivoxSecurity() { } + +bool LLVivoxVoiceP2PIncomingCall::answerInvite() { return LLVivoxVoiceClient::getInstance()->answerInvite(mCallInfo["session_handle"]); } + +void LLVivoxVoiceP2PIncomingCall::declineInvite() { LLVivoxVoiceClient::getInstance()->declineInvite(mCallInfo["session_handle"]); } diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h index 5ddb72fa24..76d92e25eb 100644 --- a/indra/newview/llvoicevivox.h +++ b/indra/newview/llvoicevivox.h @@ -51,10 +51,25 @@ class LLVivoxProtocolParser; class LLAvatarName; class LLVivoxVoiceClientMuteListObserver; +extern const std::string VIVOX_VOICE_SERVER_TYPE; + +class LLVivoxVoiceP2PIncomingCall : public LLVoiceP2PIncomingCallInterface +{ + public: + LLVivoxVoiceP2PIncomingCall(const LLSD& call_info) : mCallInfo(call_info) {} + ~LLVivoxVoiceP2PIncomingCall() override {} + + bool answerInvite() override; + void declineInvite() override; + + protected: + LLSD mCallInfo; +}; class LLVivoxVoiceClient : public LLSingleton<LLVivoxVoiceClient>, virtual public LLVoiceModuleInterface, - virtual public LLVoiceEffectInterface + virtual public LLVoiceEffectInterface, + virtual public LLVoiceP2POutgoingCallInterface { LLSINGLETON_C11(LLVivoxVoiceClient); LOG_CLASS(LLVivoxVoiceClient); @@ -112,9 +127,6 @@ public: // Send a text message to the specified user, initiating the session if necessary. // virtual BOOL sendTextMessage(const LLUUID& participant_id, const std::string& message) const {return false;}; - - // close any existing text IM session with the specified user - void endUserIMSession(const LLUUID &uuid) override; // Returns true if calling back the session URI after the session has closed is possible. // Currently this will be false only for PSTN P2P calls. @@ -134,33 +146,37 @@ public: // Note that gestures should only fire if this returns true. bool inProximalChannel() override; - void setNonSpatialChannel(const std::string &uri, - const std::string &credentials, - bool hangup_on_last_leave) override; + void setNonSpatialChannel(const LLSD& channelInfo, + bool hangup_on_last_leave) override; - bool setSpatialChannel(const std::string &uri, - const std::string &credentials) override; + bool setSpatialChannel(const LLSD& channelInfo) override; void leaveNonSpatialChannel() override; + + void processChannels(bool process) override; - void leaveChannel(void) override; - - // Returns the URI of the current channel, or an empty string if not currently in a channel. - // NOTE that it will return an empty string if it's in the process of joining a channel. - std::string getCurrentChannel() override; + void leaveChannel(void); + + bool isCurrentChannel(const LLSD &channelInfo) override; + bool compareChannels(const LLSD &channelInfo1, const LLSD &channelInfo2) override; + //@} ////////////////////////// - /// @name invitations + /// @name LLVoiceP2POutgoingCallInterface //@{ // start a voice channel with the specified user - bool hasP2PInterface() override { return true; } void callUser(const LLUUID &uuid) override; - bool isValidChannel(std::string &channelHandle) override; - bool answerInvite(std::string &channelHandle) override; - void declineInvite(std::string &channelHandle) override; + void hangup() override; //@} + + LLVoiceP2POutgoingCallInterface *getOutgoingCallInterface() override { return this; } + + LLVoiceP2PIncomingCallInterfacePtr getIncomingCallInterface(const LLSD &voice_call_info) override; + + bool answerInvite(const std::string &sessionHandle); + void declineInvite(const std::string &sessionHandle); ///////////////////////// /// @name Volume/gain @@ -172,10 +188,7 @@ public: ///////////////////////// /// @name enable disable voice and features //@{ - bool voiceEnabled() override; void setVoiceEnabled(bool enabled) override; - BOOL lipSyncEnabled() override; - void setLipSyncEnabled(BOOL enabled) override; void setMuteMic(bool muted) override; // Set the mute state of the local mic. //@} @@ -312,6 +325,8 @@ protected: static ptr_t createSession(); ~sessionState(); + + LLSD getVoiceChannelInfo(); participantStatePtr_t addParticipant(const std::string &uri); void removeParticipant(const participantStatePtr_t &participant); @@ -327,6 +342,7 @@ protected: bool isCallBackPossible(); bool isTextIMPossible(); + bool isSpatial() { return mIsSpatial; } static void for_each(sessionFunc_t func); @@ -738,10 +754,8 @@ private: bool switchChannel(std::string uri = std::string(), bool spatial = true, bool no_reconnect = false, bool is_p2p = false, std::string hash = ""); void joinSession(const sessionStatePtr_t &session); - std::string nameFromAvatar(LLVOAvatar *avatar); std::string nameFromID(const LLUUID &id); bool IDFromName(const std::string name, LLUUID &uuid); - std::string displayNameFromAvatar(LLVOAvatar *avatar); std::string sipURIFromAvatar(LLVOAvatar *avatar); std::string sipURIFromName(std::string &name); @@ -749,7 +763,7 @@ private: std::string nameFromsipURI(const std::string &uri); bool inSpatialChannel(void); - std::string getAudioSessionURI(); + LLSD getAudioSessionChannelInfo(); std::string getAudioSessionHandle(); void setHidden(bool hidden) override; //virtual @@ -805,11 +819,10 @@ private: bool mMicVolumeDirty; bool mVoiceEnabled; + bool mProcessChannels; bool mWriteInProgress; std::string mWriteString; size_t mWriteOffset; - - BOOL mLipSyncEnabled; typedef std::set<LLVoiceClientParticipantObserver*> observer_set_t; observer_set_t mParticipantObservers; diff --git a/indra/newview/llvoicewebrtc.cpp b/indra/newview/llvoicewebrtc.cpp index f276811b25..791c733dcc 100644 --- a/indra/newview/llvoicewebrtc.cpp +++ b/indra/newview/llvoicewebrtc.cpp @@ -84,6 +84,8 @@ extern LLMenuBarGL* gMenuBarView; extern void handle_voice_morphing_subscribe(); +const std::string WEBRTC_VOICE_SERVER_TYPE = "webrtc"; + namespace { const F32 MAX_AUDIO_DIST = 50.0f; @@ -94,7 +96,6 @@ namespace { const F32 SPEAKING_AUDIO_LEVEL = 0.40; static const std::string VISIBLE_VOICE_SERVER_TYPE = "WebRTC"; - static const std::string WEBRTC_VOICE_SERVER_TYPE = "webrtc"; // Don't send positional updates more frequently than this: const F32 UPDATE_THROTTLE_SECONDS = 0.1f; @@ -267,8 +268,7 @@ LLWebRTCVoiceClient::LLWebRTCVoiceClient() : mMicGain(0.0), mVoiceEnabled(false), - - mLipSyncEnabled(false), + mProcessChannels(false), mShutdownComplete(true), mPlayRequestCount(0), @@ -291,6 +291,7 @@ LLWebRTCVoiceClient::LLWebRTCVoiceClient() : mVoiceVersion.serverVersion = ""; mVoiceVersion.voiceServerType = VISIBLE_VOICE_SERVER_TYPE; + mVoiceVersion.internalVoiceServerType = WEBRTC_VOICE_SERVER_TYPE; mVoiceVersion.minorVersion = 0; mVoiceVersion.majorVersion = 2; mVoiceVersion.mBuildVersion = ""; @@ -374,7 +375,7 @@ const LLVoiceVersionInfo& LLWebRTCVoiceClient::getVersion() void LLWebRTCVoiceClient::updateSettings() { - setVoiceEnabled(voiceEnabled()); + setVoiceEnabled(LLVoiceClient::getInstance()->voiceEnabled()); setEarLocation(gSavedSettings.getS32("VoiceEarLocation")); std::string inputDevice = gSavedSettings.getString("VoiceInputAudioDevice"); @@ -383,7 +384,6 @@ void LLWebRTCVoiceClient::updateSettings() setRenderDevice(outputDevice); F32 mic_level = gSavedSettings.getF32("AudioLevelMic"); setMicGain(mic_level); - setLipSyncEnabled(gSavedSettings.getBOOL("LipSyncEnabled")); } @@ -456,7 +456,7 @@ void LLWebRTCVoiceClient::sessionState::processSessionStates() auto iter = mSessions.begin(); while (iter != mSessions.end()) { - if (!iter->second->processConnectionStates()) + if (!iter->second->processConnectionStates() && iter->second->mShuttingDown) { iter = mSessions.erase(iter); } @@ -568,8 +568,8 @@ void LLWebRTCVoiceClient::voiceConnectionCoro() { continue; } - LLVoiceVersionInfo version = LLVoiceClient::getInstance()->getVersion(); - if (version.voiceServerType != VISIBLE_VOICE_SERVER_TYPE) + + if (!mProcessChannels) { // we've switched away from webrtc voice, so shut all channels down. // leave channel can be called again and again without adverse effects. @@ -1271,43 +1271,15 @@ bool LLWebRTCVoiceClient::startParcelSession(const std::string &channelID, S32 p return true; } -bool LLWebRTCVoiceClient::startAdHocSession(const std::string &channelID, const std::string &credentials, bool hangup_on_last_leave) +bool LLWebRTCVoiceClient::startAdHocSession(const LLSD& channelInfo, bool hangup_on_last_leave) { leaveChannel(false); + std::string channelID = channelInfo["channel"]; + std::string credentials = channelInfo["credentials"]; mNextSession = addSession(channelID, sessionState::ptr_t(new adhocSessionState(channelID, credentials, hangup_on_last_leave))); return true; } -void LLWebRTCVoiceClient::joinSession(const sessionStatePtr_t &session) -{ - mNextSession = session; - - if (mSession) - { - // If we're already in a channel, or if we're joining one, terminate - // so we can rejoin with the new session data. - mSession->shutdownAllConnections(); - } -} - -void LLWebRTCVoiceClient::callUser(const LLUUID &uuid) -{ -} - -void LLWebRTCVoiceClient::endUserIMSession(const LLUUID &uuid) -{ - -} -bool LLWebRTCVoiceClient::isValidChannel(std::string &channelID) -{ - return(findP2PSession(LLUUID(channelID)) != NULL); - -} -bool LLWebRTCVoiceClient::answerInvite(std::string &channelID) -{ - return false; -} - bool LLWebRTCVoiceClient::isVoiceWorking() const { @@ -1355,16 +1327,11 @@ BOOL LLWebRTCVoiceClient::isSessionTextIMPossible(const LLUUID &session_id) return result; } - - -void LLWebRTCVoiceClient::declineInvite(std::string &sessionHandle) -{ -} void LLWebRTCVoiceClient::leaveNonSpatialChannel() { LL_DEBUGS("Voice") << "Request to leave spacial channel." << LL_ENDL; - + // Make sure we don't rejoin the current session. sessionStatePtr_t oldNextSession(mNextSession); mNextSession.reset(); @@ -1375,9 +1342,9 @@ void LLWebRTCVoiceClient::leaveNonSpatialChannel() leaveChannel(true); } -std::string LLWebRTCVoiceClient::getCurrentChannel() -{ - return getAudioSessionURI(); +void LLWebRTCVoiceClient::processChannels(bool process) +{ + mProcessChannels = process; } bool LLWebRTCVoiceClient::inProximalChannel() @@ -1385,16 +1352,6 @@ bool LLWebRTCVoiceClient::inProximalChannel() return inSpatialChannel(); } -std::string LLWebRTCVoiceClient::nameFromAvatar(LLVOAvatar *avatar) -{ - std::string result; - if(avatar) - { - result = nameFromID(avatar->getID()); - } - return result; -} - std::string LLWebRTCVoiceClient::nameFromID(const LLUUID &uuid) { std::string result; @@ -1469,11 +1426,6 @@ bool LLWebRTCVoiceClient::IDFromName(const std::string inName, LLUUID &uuid) return result; } -std::string LLWebRTCVoiceClient::displayNameFromAvatar(LLVOAvatar *avatar) -{ - return avatar->getFullname(); -} - bool LLWebRTCVoiceClient::inOrJoiningChannel(const std::string& channelID) { return (mSession && mSession->mChannelID == channelID) || (mNextSession && mNextSession->mChannelID == channelID); @@ -1500,14 +1452,17 @@ bool LLWebRTCVoiceClient::inSpatialChannel() return result; } -std::string LLWebRTCVoiceClient::getAudioSessionURI() +std::string LLWebRTCVoiceClient::getAudioSessionChannelInfo() { - std::string result; - - if(mSession) - result = mSession->mChannelID; - - return result; + LLSD result; + + if (mSession) + { + result["voice_server_type"] = WEBRTC_VOICE_SERVER_TYPE; + result["channel_uri"] = mSession->mChannelID; + } + + return result; } ///////////////////////////// @@ -1670,8 +1625,6 @@ bool LLWebRTCVoiceClient::channelFromRegion(LLViewerRegion *region, std::string void LLWebRTCVoiceClient::leaveChannel(bool stopTalking) { - mChannelName.clear(); - if (mSession) { deleteSession(mSession); @@ -1689,6 +1642,19 @@ void LLWebRTCVoiceClient::leaveChannel(bool stopTalking) } } +bool LLWebRTCVoiceClient::isCurrentChannel(const LLSD &channelInfo) +{ + return (channelInfo["voice_server_type"].asString() == WEBRTC_VOICE_SERVER_TYPE) && + (sessionState::hasSession(channelInfo["session_handle"].asString())); +} + +bool LLWebRTCVoiceClient::compareChannels(const LLSD &channelInfo1, const LLSD &channelInfo2) +{ + return (channelInfo1["voice_server_type"] == WEBRTC_VOICE_SERVER_TYPE) && + (channelInfo1["voice_server_type"] == channelInfo2["voice_server_type"]) && + (channelInfo1["sip_uri"] == channelInfo2["sip_uri"]); +} + void LLWebRTCVoiceClient::setMuteMic(bool muted) { @@ -1779,32 +1745,6 @@ void LLWebRTCVoiceClient::setVoiceEnabled(bool enabled) } } -bool LLWebRTCVoiceClient::voiceEnabled() -{ - return gSavedSettings.getBOOL("EnableVoiceChat") && - !gSavedSettings.getBOOL("CmdLineDisableVoice") && - !gNonInteractive; -} - -void LLWebRTCVoiceClient::setLipSyncEnabled(BOOL enabled) -{ - mLipSyncEnabled = enabled; -} - -BOOL LLWebRTCVoiceClient::lipSyncEnabled() -{ - - if ( mVoiceEnabled ) - { - return mLipSyncEnabled; - } - else - { - return FALSE; - } -} - - void LLWebRTCVoiceClient::setEarLocation(S32 loc) { if(mEarLocation != loc) @@ -2050,7 +1990,7 @@ LLWebRTCVoiceClient::sessionState::sessionState() : /*static*/ void LLWebRTCVoiceClient::sessionState::addSession( - const std::string &channelID, + const std::string & channelID, LLWebRTCVoiceClient::sessionState::ptr_t& session) { mSessions[channelID] = session; @@ -2152,7 +2092,6 @@ LLWebRTCVoiceClient::sessionStatePtr_t LLWebRTCVoiceClient::findP2PSession(const } - void LLWebRTCVoiceClient::sessionState::shutdownAllConnections() { mShuttingDown = true; @@ -2162,6 +2101,11 @@ void LLWebRTCVoiceClient::sessionState::shutdownAllConnections() } } +void LLWebRTCVoiceClient::sessionState::revive() +{ + mShuttingDown = false; +} + LLWebRTCVoiceClient::sessionStatePtr_t LLWebRTCVoiceClient::addSession(const std::string &channel_id, sessionState::ptr_t session) { @@ -2187,6 +2131,8 @@ LLWebRTCVoiceClient::sessionStatePtr_t LLWebRTCVoiceClient::addSession(const std { // Found an existing session LL_DEBUGS("Voice") << "Attempting to add already-existing session " << channel_id << LL_ENDL; + existingSession->revive(); + return existingSession; } } @@ -2296,19 +2242,18 @@ void LLWebRTCVoiceClient::notifyStatusObservers(LLVoiceClientStatusObserver::ESt LL_DEBUGS("Voice") << " " << LLVoiceClientStatusObserver::status2string(status) - << ", session URI " << getAudioSessionURI() + << ", session channelInfo " << getAudioSessionChannelInfo() << ", proximal is " << inSpatialChannel() << LL_ENDL; - mIsProcessingChannels = - (status == LLVoiceClientStatusObserver::STATUS_LOGGED_IN || status == LLVoiceClientStatusObserver::STATUS_JOINED); + mIsProcessingChannels = status == LLVoiceClientStatusObserver::STATUS_JOINED; for (status_observer_set_t::iterator it = mStatusObservers.begin(); it != mStatusObservers.end(); ) { LLVoiceClientStatusObserver* observer = *it; - observer->onChange(status, getAudioSessionURI(), inSpatialChannel()); + observer->onChange(status, getAudioSessionChannelInfo(), inSpatialChannel()); // In case onError() deleted an entry. it = mStatusObservers.upper_bound(observer); } @@ -2459,18 +2404,19 @@ void LLVoiceWebRTCConnection::OnIceCandidate(const llwebrtc::LLWebRTCIceCandidat void LLVoiceWebRTCConnection::onIceUpdateComplete(bool ice_completed, const LLSD &result) { + mOutstandingRequests--; if (LLWebRTCVoiceClient::isShuttingDown()) { return; } mTrickling = false; - mOutstandingRequests--; } void LLVoiceWebRTCConnection::onIceUpdateError(int retries, std::string url, LLSD body, bool ice_completed, const LLSD &result) { if (LLWebRTCVoiceClient::isShuttingDown()) { + mOutstandingRequests--; return; } LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); @@ -2548,41 +2494,42 @@ void LLVoiceWebRTCConnection::processIceUpdates() LLViewerRegion *regionp = LLWorld::instance().getRegionFromID(mRegionID); if (!regionp || !regionp->capabilitiesReceived()) { - LL_DEBUGS("Voice") << "no capabilities for ice gathering; waiting " << LL_ENDL; - return; + LL_DEBUGS("Voice") << "no capabilities for ice gathering; waiting " << LL_ENDL; + return; } std::string url = regionp->getCapability("VoiceSignalingRequest"); if (url.empty()) { - return; + return; } LL_DEBUGS("Voice") << "region ready to complete voice signaling; url=" << url << LL_ENDL; if (!mIceCandidates.empty()) { - LLSD candidates = LLSD::emptyArray(); - for (auto &ice_candidate : mIceCandidates) - { - LLSD body_candidate; - body_candidate["sdpMid"] = ice_candidate.sdp_mid; - body_candidate["sdpMLineIndex"] = ice_candidate.mline_index; - body_candidate["candidate"] = ice_candidate.candidate; - candidates.append(body_candidate); - } - body["candidates"] = candidates; - mIceCandidates.clear(); + LLSD candidates = LLSD::emptyArray(); + for (auto &ice_candidate : mIceCandidates) + { + LLSD body_candidate; + body_candidate["sdpMid"] = ice_candidate.sdp_mid; + body_candidate["sdpMLineIndex"] = ice_candidate.mline_index; + body_candidate["candidate"] = ice_candidate.candidate; + candidates.append(body_candidate); + } + body["candidates"] = candidates; + mIceCandidates.clear(); } else if (mIceCompleted) { - LLSD body_candidate; - body_candidate["completed"] = true; - body["candidate"] = body_candidate; - iceCompleted = mIceCompleted; - mIceCompleted = false; + LLSD body_candidate; + body_candidate["completed"] = true; + body["candidate"] = body_candidate; + iceCompleted = mIceCompleted; + mIceCompleted = false; } body["viewer_session"] = mViewerSession; + body["voice_server_type"] = WEBRTC_VOICE_SERVER_TYPE; LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter( @@ -2694,6 +2641,7 @@ bool LLVoiceWebRTCConnection::breakVoiceConnection(bool corowait) LLSD body; body["logout"] = TRUE; body["viewer_session"] = mViewerSession; + body["voice_server_type"] = WEBRTC_VOICE_SERVER_TYPE; LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpPost( url, @@ -2708,6 +2656,7 @@ bool LLVoiceWebRTCConnection::breakVoiceConnection(bool corowait) void LLVoiceWebRTCConnection::OnVoiceDisconnectionRequestSuccess(const LLSD &result) { + mOutstandingRequests--; if (LLWebRTCVoiceClient::isShuttingDown()) { return; @@ -2722,13 +2671,13 @@ void LLVoiceWebRTCConnection::OnVoiceDisconnectionRequestSuccess(const LLSD &res { setVoiceConnectionState(VOICE_STATE_SESSION_EXIT); } - mOutstandingRequests--; } void LLVoiceWebRTCConnection::OnVoiceDisconnectionRequestFailure(std::string url, int retries, LLSD body, const LLSD &result) { if (LLWebRTCVoiceClient::isShuttingDown()) { + mOutstandingRequests--; return; } if (retries >= 0) @@ -2756,6 +2705,7 @@ void LLVoiceWebRTCConnection::OnVoiceDisconnectionRequestFailure(std::string url void LLVoiceWebRTCConnection::OnVoiceConnectionRequestSuccess(const LLSD &result) { + mOutstandingRequests--; if (LLWebRTCVoiceClient::isShuttingDown()) { return; @@ -2772,7 +2722,6 @@ void LLVoiceWebRTCConnection::OnVoiceConnectionRequestSuccess(const LLSD &result { LL_WARNS("Voice") << "Invalid voice provision request result:" << result << LL_ENDL; setVoiceConnectionState(VOICE_STATE_SESSION_RETRY); - mOutstandingRequests--; return; } @@ -2780,13 +2729,13 @@ void LLVoiceWebRTCConnection::OnVoiceConnectionRequestSuccess(const LLSD &result << " channel sdp " << mRemoteChannelSDP << LL_ENDL; mWebRTCPeerConnection->AnswerAvailable(mRemoteChannelSDP); - mOutstandingRequests--; } void LLVoiceWebRTCConnection::OnVoiceConnectionRequestFailure(std::string url, int retries, LLSD body, const LLSD &result) { if (LLWebRTCVoiceClient::isShuttingDown()) { + mOutstandingRequests--; return; } if (retries >= 0) @@ -3117,6 +3066,8 @@ bool LLVoiceWebRTCSpatialConnection::requestVoiceConnection() body["parcel_local_id"] = mParcelLocalID; } + body["voice_server_type"] = WEBRTC_VOICE_SERVER_TYPE; + LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpPost( url, LLCore::HttpRequest::DEFAULT_POLICY_ID, diff --git a/indra/newview/llvoicewebrtc.h b/indra/newview/llvoicewebrtc.h index 16bcadb144..0bfbca8079 100644 --- a/indra/newview/llvoicewebrtc.h +++ b/indra/newview/llvoicewebrtc.h @@ -26,7 +26,6 @@ #ifndef LL_VOICE_WEBRTC_H #define LL_VOICE_WEBRTC_H -class LLVOAvatar; class LLWebRTCProtocolParser; #include "lliopipe.h" @@ -58,6 +57,8 @@ class LLAvatarName; class LLVoiceWebRTCConnection; typedef boost::shared_ptr<LLVoiceWebRTCConnection> connectionPtr_t; +extern const std::string WEBRTC_VOICE_SERVER_TYPE; + class LLWebRTCVoiceClient : public LLSingleton<LLWebRTCVoiceClient>, virtual public LLVoiceModuleInterface, virtual public LLVoiceEffectInterface, @@ -123,9 +124,6 @@ public: // Send a text message to the specified user, initiating the session if necessary. // virtual BOOL sendTextMessage(const LLUUID& participant_id, const std::string& message) const {return false;}; - - // close any existing text IM session with the specified user - void endUserIMSession(const LLUUID &uuid) override; // Returns true if calling back the session URI after the session has closed is possible. // Currently this will be false only for PSTN P2P calls. @@ -145,39 +143,31 @@ public: // Note that gestures should only fire if this returns true. bool inProximalChannel() override; - void setNonSpatialChannel(const std::string& uri, const std::string& credentials, bool hangup_on_last_leave) override { - startAdHocSession(uri, credentials, hangup_on_last_leave); + void setNonSpatialChannel(const LLSD& channelInfo, bool hangup_on_last_leave) override + { + startAdHocSession(channelInfo, hangup_on_last_leave); } - bool setSpatialChannel(const std::string &uri, const std::string &credentials) override + bool setSpatialChannel(const LLSD &channelInfo) override { - leaveNonSpatialChannel(); - // this is a vivox-related call + processChannels(true); + return true; } void leaveNonSpatialChannel() override; - - void leaveChannel(void) override { leaveChannel(true); } + + void processChannels(bool process) override; void leaveChannel(bool stopTalking); - - // Returns the URI of the current channel, or an empty string if not currently in a channel. - // NOTE that it will return an empty string if it's in the process of joining a channel. - std::string getCurrentChannel() override; - //@} - - - ////////////////////////// - /// @name invitations - //@{ - // start a voice channel with the specified user - bool hasP2PInterface() override { return false; } - void callUser(const LLUUID &uuid) override; - bool isValidChannel(std::string &channelID) override; - bool answerInvite(std::string &channelID) override; - void declineInvite(std::string &channelID) override; + + bool isCurrentChannel(const LLSD &channelInfo) override; + bool compareChannels(const LLSD &channelInfo1, const LLSD &channelInfo2) override; //@} + + LLVoiceP2POutgoingCallInterface *getOutgoingCallInterface() override { return nullptr; } + + LLVoiceP2PIncomingCallInterfacePtr getIncomingCallInterface(const LLSD &voice_call_info) override { return nullptr; } ///////////////////////// /// @name Volume/gain @@ -189,10 +179,7 @@ public: ///////////////////////// /// @name enable disable voice and features //@{ - bool voiceEnabled() override; void setVoiceEnabled(bool enabled) override; - BOOL lipSyncEnabled() override; - void setLipSyncEnabled(BOOL enabled) override; void setMuteMic(bool muted) override; // Set the mute state of the local mic. //@} @@ -339,6 +326,7 @@ public: static ptr_t matchSessionByChannelID(const std::string& channel_id); void shutdownAllConnections(); + void revive(); bool isCallBackPossible(); bool isTextIMPossible(); @@ -593,7 +581,6 @@ private: std::string mMainSessionGroupHandle; // handle of the "main" session group. - std::string mChannelName; // Name of the channel to be looked up bool mAreaVoiceDisabled; sessionStatePtr_t mSession; // Session state for the current session @@ -616,21 +603,16 @@ private: bool startEstateSession(); bool startParcelSession(const std::string& channelID, S32 parcelID); - bool startAdHocSession(const std::string& channelID, const std::string& credentials, bool hangup_on_last_leave); - - void joinSession(const sessionStatePtr_t &session); + bool startAdHocSession(const LLSD &channelInfo, bool hangup_on_last_leave); - std::string nameFromAvatar(LLVOAvatar *avatar); std::string nameFromID(const LLUUID &id); bool IDFromName(const std::string name, LLUUID &uuid); - std::string displayNameFromAvatar(LLVOAvatar *avatar); - bool inSpatialChannel(); bool inOrJoiningChannel(const std::string &channelID); bool inEstateChannel(); - std::string getAudioSessionURI(); + std::string getAudioSessionChannelInfo(); void setHidden(bool hidden) override; //virtual @@ -674,6 +656,7 @@ private: F32 mMicGain; bool mVoiceEnabled; + bool mProcessChannels; BOOL mLipSyncEnabled; |