From d947912bb0d39ed9d6f8710f09190a5dfbcc9cd0 Mon Sep 17 00:00:00 2001 From: Lirusaito Date: Tue, 11 Jun 2013 15:41:53 -0400 Subject: [PATCH] [Voice Update] Start/End call functions Adds llvoicecallhandler.cpp Enables the Group and Avatar Actions requiring the voice refactor. Adds autoStartCallOnStartup, processAgentListUpdates, startCall, and endCall to LLIMMgr. Gives llimpanel some LLIMModel functionality to see if a floater was opened with the intent of being a call. Cleans up LLIMPanel with new functions from the voice refactor. --- indra/newview/CMakeLists.txt | 1 + indra/newview/llavataractions.cpp | 6 +- indra/newview/llgroupactions.cpp | 2 - indra/newview/llimpanel.cpp | 76 +++------- indra/newview/llimpanel.h | 13 +- indra/newview/llimview.cpp | 198 +++++++++++++++++---------- indra/newview/llimview.h | 20 ++- indra/newview/llvoicecallhandler.cpp | 69 ++++++++++ 8 files changed, 238 insertions(+), 147 deletions(-) create mode 100644 indra/newview/llvoicecallhandler.cpp diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 5d40fc1fd..5d16b11dc 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -521,6 +521,7 @@ set(viewer_SOURCE_FILES llvoclouds.cpp llvograss.cpp llvoground.cpp + llvoicecallhandler.cpp llvoicechannel.cpp llvoiceclient.cpp llvoiceremotectrl.cpp diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index bdb57a10f..9be913ae8 100644 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -204,11 +204,10 @@ void LLAvatarActions::endIM(const LLUUID& id) } } -/* Singu TODO: Voice refactor static void on_avatar_name_cache_start_call(const LLUUID& agent_id, const LLAvatarName& av_name) { - LLUUID session_id = gIMMgr->addSession(LLCacheName::cleanFullName(av_name.getLegacyName()), IM_NOTHING_SPECIAL, agent_id, true); + LLUUID session_id = gIMMgr->addSession(LLCacheName::cleanFullName(av_name.getLegacyName()), IM_NOTHING_SPECIAL, agent_id); if (session_id.notNull()) { gIMMgr->startCall(session_id); @@ -270,7 +269,7 @@ void LLAvatarActions::startAdhocCall(const uuid_vec_t& ids) // create the new ad hoc voice session const std::string title = LLTrans::getString("conference-title"); LLUUID session_id = gIMMgr->addSession(title, IM_SESSION_CONFERENCE_START, - ids[0], id_array, true); + ids[0], id_array); if (session_id.isNull()) { return; @@ -280,7 +279,6 @@ void LLAvatarActions::startAdhocCall(const uuid_vec_t& ids) make_ui_sound("UISndStartIM"); } -*/ /* AD *TODO: Is this function needed any more? I fixed it a bit(added check for canCall), but it appears that it is not used diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp index d5d9ecad4..ade7e1d1f 100644 --- a/indra/newview/llgroupactions.cpp +++ b/indra/newview/llgroupactions.cpp @@ -128,7 +128,6 @@ void LLGroupActions::search() LLFloaterDirectory::showGroups(); } -/* Singu TODO: Voice refactor // static void LLGroupActions::startCall(const LLUUID& group_id) { @@ -162,7 +161,6 @@ void LLGroupActions::startCall(const LLUUID& group_id) make_ui_sound("UISndStartIM"); } -*/ // static void LLGroupActions::join(const LLUUID& group_id) diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp index edd499610..b1479ffe9 100644 --- a/indra/newview/llimpanel.cpp +++ b/indra/newview/llimpanel.cpp @@ -315,7 +315,7 @@ LLFloaterIMPanel::LLFloaterIMPanel( mSentTypingState(TRUE), mNumUnreadMessages(0), mShowSpeakersOnConnect(TRUE), - mAutoConnect(FALSE), + mStartCallOnInitialize(false), mTextIMPossible(TRUE), mProfileButtonEnabled(TRUE), mCallBackEnabled(TRUE), @@ -352,7 +352,7 @@ LLFloaterIMPanel::LLFloaterIMPanel( mTypingLineStartIndex(0), mSentTypingState(TRUE), mShowSpeakersOnConnect(TRUE), - mAutoConnect(FALSE), + mStartCallOnInitialize(false), mTextIMPossible(TRUE), mProfileButtonEnabled(TRUE), mCallBackEnabled(TRUE), @@ -574,8 +574,8 @@ BOOL LLFloaterIMPanel::postBuild() if (LLUICtrl* ctrl = findChild("rp_mode")) ctrl->setCommitCallback(boost::bind(&LLFloaterIMPanel::onRPMode, this, _2)); - childSetAction("start_call_btn", onClickStartCall, this); - childSetAction("end_call_btn", onClickEndCall, this); + getChild("start_call_btn")->setCommitCallback(boost::bind(&LLIMMgr::startCall, gIMMgr, mOtherParticipantUUID, LLVoiceChannel::OUTGOING_CALL)); + getChild("end_call_btn")->setCommitCallback(boost::bind(&LLIMMgr::endCall, gIMMgr, mOtherParticipantUUID)); getChild("send_btn")->setCommitCallback(boost::bind(&LLFloaterIMPanel::onSendMsg,this)); if (LLButton* btn = findChild("toggle_active_speakers_btn")) btn->setCommitCallback(boost::bind(&LLFloaterIMPanel::onClickToggleActiveSpeakers, this, _2)); @@ -600,8 +600,8 @@ BOOL LLFloaterIMPanel::postBuild() if (mDialog == IM_NOTHING_SPECIAL) { - childSetAction("mute_btn", onClickMuteVoice, this); - childSetCommitCallback("speaker_volume", onVolumeChange, this); + getChild("mute_btn")->setCommitCallback(boost::bind(&LLFloaterIMPanel::onClickMuteVoice, this)); + getChild("speaker_volume")->setCommitCallback(boost::bind(&LLVoiceClient::setUserVolume, LLVoiceClient::getInstance(), mOtherParticipantUUID, _2)); } setDefaultBtn("send_btn"); @@ -625,33 +625,16 @@ void* LLFloaterIMPanel::createSpeakersPanel(void* data) return floaterp->mSpeakerPanel; } -//static -void LLFloaterIMPanel::onClickMuteVoice(void* user_data) +void LLFloaterIMPanel::onClickMuteVoice() { - LLFloaterIMPanel* floaterp = (LLFloaterIMPanel*)user_data; - if (floaterp) + LLMute mute(mOtherParticipantUUID, getTitle(), LLMute::AGENT); + if (!LLMuteList::getInstance()->isMuted(mOtherParticipantUUID, LLMute::flagVoiceChat)) { - BOOL is_muted = LLMuteList::getInstance()->isMuted(floaterp->mOtherParticipantUUID, LLMute::flagVoiceChat); - - LLMute mute(floaterp->mOtherParticipantUUID, floaterp->getTitle(), LLMute::AGENT); - if (!is_muted) - { - LLMuteList::getInstance()->add(mute, LLMute::flagVoiceChat); - } - else - { - LLMuteList::getInstance()->remove(mute, LLMute::flagVoiceChat); - } + LLMuteList::getInstance()->add(mute, LLMute::flagVoiceChat); } -} - -//static -void LLFloaterIMPanel::onVolumeChange(LLUICtrl* source, void* user_data) -{ - LLFloaterIMPanel* floaterp = (LLFloaterIMPanel*)user_data; - if (floaterp) + else { - LLVoiceClient::getInstance()->setUserVolume(floaterp->mOtherParticipantUUID, (F32)source->getValue().asReal()); + LLMuteList::getInstance()->remove(mute, LLMute::flagVoiceChat); } } @@ -670,7 +653,7 @@ void LLFloaterIMPanel::draw() mEndCallBtn->setVisible(LLVoiceClient::getInstance()->voiceEnabled() && mVoiceChannel->getState() >= LLVoiceChannel::STATE_CALL_STARTED); mStartCallBtn->setVisible(LLVoiceClient::getInstance()->voiceEnabled() && mVoiceChannel->getState() < LLVoiceChannel::STATE_CALL_STARTED); mStartCallBtn->setEnabled(enable_connect); - mSendBtn->setEnabled(!childGetValue("chat_editor").asString().empty()); + mSendBtn->setEnabled(!mInputEditor->getValue().asString().empty()); LLPointer self_speaker = mSpeakers->findSpeaker(gAgent.getID()); if(!mTextIMPossible) @@ -689,12 +672,6 @@ void LLFloaterIMPanel::draw() mInputEditor->setLabel(getString("default_text_label")); } - if (mAutoConnect && enable_connect) - { - onClickStartCall(this); - mAutoConnect = FALSE; - } - // show speakers window when voice first connects if (mShowSpeakersOnConnect && mVoiceChannel->isActive()) { @@ -1111,14 +1088,6 @@ void LLFloaterIMPanel::onClickStartCall(void* userdata) self->mVoiceChannel->activate(); } -// static -void LLFloaterIMPanel::onClickEndCall(void* userdata) -{ - LLFloaterIMPanel* self = (LLFloaterIMPanel*) userdata; - - self->getVoiceChannel()->deactivate(); -} - void LLFloaterIMPanel::onClickToggleActiveSpeakers(const LLSD& value) { childSetVisible("active_speakers_panel", !value); @@ -1454,11 +1423,6 @@ LL_WARNS("Splitting") << "Pos: " << pos << " next_split: " << next_split << LL_E mSentTypingState = TRUE; } -void LLFloaterIMPanel::updateSpeakersList(const LLSD& speaker_updates) -{ - mSpeakers->updateSpeakers(speaker_updates); -} - void LLFloaterIMPanel::processSessionUpdate(const LLSD& session_update) { if ( @@ -1482,11 +1446,6 @@ void LLFloaterIMPanel::processSessionUpdate(const LLSD& session_update) } } -void LLFloaterIMPanel::setSpeakers(const LLSD& speaker_list) -{ - mSpeakers->setSpeakers(speaker_list); -} - void LLFloaterIMPanel::sessionInitReplyReceived(const LLUUID& session_id) { mSessionUUID = session_id; @@ -1512,11 +1471,12 @@ void LLFloaterIMPanel::sessionInitReplyReceived(const LLUUID& session_id) mOtherParticipantUUID, mDialog); } -} -void LLFloaterIMPanel::requestAutoConnect() -{ - mAutoConnect = TRUE; + // auto-start the call on session initialization? + if (mStartCallOnInitialize) + { + gIMMgr->startCall(mSessionUUID); + } } void LLFloaterIMPanel::setTyping(BOOL typing) diff --git a/indra/newview/llimpanel.h b/indra/newview/llimpanel.h index 7d4d1fe71..0f659a820 100644 --- a/indra/newview/llimpanel.h +++ b/indra/newview/llimpanel.h @@ -121,20 +121,15 @@ public: static void* createSpeakersPanel(void* data); //callbacks for P2P muting and volume control - static void onClickMuteVoice(void* user_data); - static void onVolumeChange(LLUICtrl* source, void* user_data); + void onClickMuteVoice(); const LLUUID& getSessionID() const { return mSessionUUID; } const LLUUID& getOtherParticipantID() const { return mOtherParticipantUUID; } - void updateSpeakersList(const LLSD& speaker_updates); void processSessionUpdate(const LLSD& update); - void setSpeakers(const LLSD& speaker_list); LLVoiceChannel* getVoiceChannel() { return mVoiceChannel; } LLIMSpeakerMgr* getSpeakerManager() const { return mSpeakers; } // Singu TODO: LLIMModel::getSpeakerManager EInstantMessage getDialogType() const { return mDialog; } - void requestAutoConnect(); - void sessionInitReplyReceived(const LLUUID& im_session_id); // Handle other participant in the session typing. @@ -161,6 +156,10 @@ public: bool isGroupSessionType() const { return mSessionType == GROUP_SESSION;} SType mSessionType; + // LLIMModel Functionality + bool getSessionInitialized() const { return mSessionInitialized; } + bool mStartCallOnInitialize; + private: // called by constructors void init(const std::string& session_label); @@ -236,8 +235,6 @@ private: BOOL mShowSpeakersOnConnect; - BOOL mAutoConnect; - BOOL mTextIMPossible; BOOL mProfileButtonEnabled; BOOL mCallBackEnabled; diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 06ac47b5b..c025bfbf6 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -53,6 +53,7 @@ #include "llfloaterchatterbox.h" #include "llhttpnode.h" #include "llimpanel.h" +#include "llnotificationsutil.h" #include "llsdserialize.h" #include "llspeakers.h" #include "lltabcontainer.h" @@ -60,7 +61,6 @@ #include "llviewermenu.h" #include "llviewermessage.h" #include "llviewerwindow.h" -#include "llvoicechannel.h" #include "llnotify.h" #include "llviewerregion.h" @@ -115,6 +115,7 @@ LLColor4 agent_chat_color(const LLUUID& id, const std::string& name, bool local_ //{ // return (LLStringUtil::compareDict( a->mName, b->mName ) < 0); //} + class LLViewerChatterBoxInvitationAcceptResponder : public LLHTTPClient::ResponderWithResult { public: @@ -130,10 +131,9 @@ public: { if ( gIMMgr) { - LLFloaterIMPanel* floaterp = - gIMMgr->findFloaterBySession(mSessionID); - - if (floaterp) + LLFloaterIMPanel* floater = gIMMgr->findFloaterBySession(mSessionID); + LLIMSpeakerMgr* speaker_mgr = floater ? floater->getSpeakerManager() : NULL; + if (speaker_mgr) { //we've accepted our invitation //and received a list of agents that were @@ -147,26 +147,26 @@ public: //but unfortunately, our base that we are receiving here //may not be the most up to date. It was accurate at //some point in time though. - floaterp->setSpeakers(content); + speaker_mgr->setSpeakers(content); //we now have our base of users in the session //that was accurate at some point, but maybe not now //so now we apply all of the udpates we've received //in case of race conditions - floaterp->updateSpeakersList( - gIMMgr->getPendingAgentListUpdates(mSessionID)); + speaker_mgr->updateSpeakers(gIMMgr->getPendingAgentListUpdates(mSessionID)); + } - if ( mInvitiationType == LLIMMgr::INVITATION_TYPE_VOICE ) - { - floaterp->requestAutoConnect(); - LLFloaterIMPanel::onClickStartCall(floaterp); - // always open IM window when connecting to voice - LLFloaterChatterBox::showInstance(TRUE); - } - else if ( mInvitiationType == LLIMMgr::INVITATION_TYPE_IMMEDIATE ) - { - LLFloaterChatterBox::showInstance(TRUE); - } + if (LLIMMgr::INVITATION_TYPE_VOICE == mInvitiationType) + { + gIMMgr->startCall(mSessionID, LLVoiceChannel::INCOMING_CALL); + } + + if ((mInvitiationType == LLIMMgr::INVITATION_TYPE_VOICE + || mInvitiationType == LLIMMgr::INVITATION_TYPE_IMMEDIATE) + && gIMMgr->hasSession(mSessionID)) + { + // always open IM window when connecting to voice + LLFloaterChatterBox::showInstance(TRUE); } gIMMgr->clearPendingAgentListUpdates(mSessionID); @@ -176,6 +176,8 @@ public: /*virtual*/ void error(U32 statusNum, const std::string& reason) { + llwarns << "LLViewerChatterBoxInvitationAcceptResponder error [status:" + << statusNum << "]: " << reason << llendl; //throw something back to the viewer here? if ( gIMMgr ) { @@ -286,11 +288,14 @@ protected: 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 = LLNotification::getSelectedOption(notification, response); + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); switch(option) { case 0: // accept @@ -304,16 +309,10 @@ bool inviteUserResponse(const LLSD& notification, const LLSD& response) payload["session_handle"].asString(), payload["session_uri"].asString()); - LLFloaterIMPanel* im_floater = - gIMMgr->findFloaterBySession( - session_id); - if (im_floater) - { - im_floater->requestAutoConnect(); - LLFloaterIMPanel::onClickStartCall(im_floater); - // always open IM window when connecting to voice - LLFloaterChatterBox::showInstance(session_id); - } + gIMMgr->startCall(session_id); + + // always open IM window when connecting to voice + LLFloaterChatterBox::showInstance(session_id); gIMMgr->clearPendingAgentListUpdates(session_id); gIMMgr->clearPendingInvitation(session_id); @@ -355,11 +354,8 @@ bool inviteUserResponse(const LLSD& notification, const LLSD& response) { if (type == IM_SESSION_P2P_INVITE) { - if(LLVoiceClient::instanceExists()) - { - std::string s = payload["session_handle"].asString(); - LLVoiceClient::getInstance()->declineInvite(s); - } + std::string s = payload["session_handle"].asString(); + LLVoiceClient::getInstance()->declineInvite(s); } else { @@ -688,6 +684,22 @@ BOOL LLIMMgr::isIMSessionOpen(const LLUUID& uuid) return FALSE; } +void LLIMMgr::autoStartCallOnStartup(const LLUUID& session_id) +{ + // Singu TODO: LLIMModel + LLFloaterIMPanel* floater = findFloaterBySession(session_id); + if (!floater) return; + + if (floater->getSessionInitialized()) + { + startCall(session_id); + } + else + { + floater->mStartCallOnInitialize = true; + } +} + LLUUID LLIMMgr::addP2PSession(const std::string& name, const LLUUID& other_participant_id, const std::string& voice_session_handle, @@ -1025,6 +1037,31 @@ void LLIMMgr::clearPendingInvitation(const LLUUID& session_id) } } +void LLIMMgr::processAgentListUpdates(const LLUUID& session_id, const LLSD& body) +{ + LLFloaterIMPanel* im_floater = gIMMgr->findFloaterBySession(session_id); + if (!im_floater) return; + LLIMSpeakerMgr* speaker_mgr = im_floater->getSpeakerManager(); + if (speaker_mgr) + { + speaker_mgr->updateSpeakers(body); + + // also the same call is added into LLVoiceClient::participantUpdatedEvent because + // sometimes it is called AFTER LLViewerChatterBoxSessionAgentListUpdates::post() + // when moderation state changed too late. See EXT-3544. + speaker_mgr->update(true); + } + else + { + //we don't have a speaker manager yet..something went wrong + //we are probably receiving an update here before + //a start or an acceptance of an invitation. Race condition. + gIMMgr->addPendingAgentListUpdates( + session_id, + body); + } +} + LLSD LLIMMgr::getPendingAgentListUpdates(const LLUUID& session_id) { if ( mPendingAgentListUpdates.has(session_id.asString()) ) @@ -1105,6 +1142,39 @@ void LLIMMgr::clearPendingAgentListUpdates(const LLUUID& session_id) } } +bool LLIMMgr::startCall(const LLUUID& session_id, LLVoiceChannel::EDirection direction) +{ + // Singu TODO: LLIMModel + LLFloaterIMPanel* floater = gIMMgr->findFloaterBySession(session_id); + if (!floater) return false; + + LLVoiceChannel* voice_channel = floater->getVoiceChannel(); + if (!voice_channel) return false; + + voice_channel->setCallDirection(direction); + voice_channel->activate(); + return true; +} + +bool LLIMMgr::endCall(const LLUUID& session_id) +{ + // Singu TODO: LLIMModel + LLFloaterIMPanel* floater = gIMMgr->findFloaterBySession(session_id); + if (!floater) return false; + + LLVoiceChannel* voice_channel = floater->getVoiceChannel(); + if (!voice_channel) return false; + + voice_channel->deactivate(); + /*LLIMModel::LLIMSession* im_session = LLIMModel::getInstance()->findIMSession(session_id); + if (im_session)*/ + { + // need to update speakers' state + floater->getSpeakerManager()->update(FALSE); + } + return true; +} + // create a floater and update internal representation for // consistency. Returns the pointer, caller (the class instance since // it is a private method) is not responsible for deleting the @@ -1418,35 +1488,30 @@ public: if ( success ) { session_id = body["session_id"].asUUID(); - gIMMgr->updateFloaterSessionID( - temp_session_id, - session_id); - LLFloaterIMPanel* floaterp = gIMMgr->findFloaterBySession(session_id); - if (floaterp) + // Singu TODO: LLIMModel + gIMMgr->updateFloaterSessionID(temp_session_id, session_id); + + LLFloaterIMPanel* im_floater = gIMMgr->findFloaterBySession(session_id); + LLIMSpeakerMgr* speaker_mgr = im_floater ? im_floater->getSpeakerManager() : NULL; + if (speaker_mgr) { - floaterp->setSpeakers(body); - - //apply updates we've possibly received previously - floaterp->updateSpeakersList( - gIMMgr->getPendingAgentListUpdates(session_id)); + speaker_mgr->setSpeakers(body); + speaker_mgr->updateSpeakers(gIMMgr->getPendingAgentListUpdates(session_id)); + } + if (im_floater) + { if ( body.has("session_info") ) { - floaterp->processSessionUpdate(body["session_info"]); + im_floater->processSessionUpdate(body["session_info"]); } - - //apply updates we've possibly received previously - floaterp->updateSpeakersList( - gIMMgr->getPendingAgentListUpdates(session_id)); } + gIMMgr->clearPendingAgentListUpdates(session_id); } else { - //throw an error dialog and close the temp session's floater - LLFloaterIMPanel* floater = gIMMgr->findFloaterBySession(temp_session_id); - - if ( floater ) + if (LLFloaterIMPanel* floater = gIMMgr->findFloaterBySession(temp_session_id)) { floater->showSessionStartError(body["error"].asString()); } @@ -1526,21 +1591,8 @@ public: const LLSD& context, const LLSD& input) const { - LLFloaterIMPanel* floaterp = gIMMgr->findFloaterBySession(input["body"]["session_id"].asUUID()); - if (floaterp) - { - floaterp->updateSpeakersList( - input["body"]); - } - else - { - //we don't have a floater yet..something went wrong - //we are probably receiving an update here before - //a start or an acceptance of an invitation. Race condition. - gIMMgr->addPendingAgentListUpdates( - input["body"]["session_id"].asUUID(), - input["body"]); - } + const LLUUID& session_id = input["body"]["session_id"].asUUID(); + gIMMgr->processAgentListUpdates(session_id, input["body"]); } }; @@ -1553,12 +1605,12 @@ public: const LLSD& input) const { LLUUID session_id = input["body"]["session_id"].asUUID(); - LLFloaterIMPanel* floaterp = gIMMgr->findFloaterBySession(session_id); - if (floaterp) + LLFloaterIMPanel* im_floater = gIMMgr->findFloaterBySession(session_id); + if ( im_floater ) { - floaterp->processSessionUpdate(input["body"]["info"]); + im_floater->processSessionUpdate(input["body"]["info"]); } - LLIMSpeakerMgr* im_mgr = floaterp ? floaterp->getSpeakerManager() : NULL; //LLIMModel::getInstance()->getSpeakerManager(session_id); + LLIMSpeakerMgr* im_mgr = im_floater ? im_floater->getSpeakerManager() : NULL; //LLIMModel::getInstance()->getSpeakerManager(session_id); if (im_mgr) { im_mgr->processSessionUpdate(input["body"]["info"]); diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h index 4db4b75f9..3e7bc6fff 100644 --- a/indra/newview/llimview.h +++ b/indra/newview/llimview.h @@ -36,12 +36,12 @@ #include "llmultifloater.h" #include "llinstantmessage.h" #include "lluuid.h" +#include "llvoicechannel.h" + class LLFloaterChatterBox; -class LLUUID; class LLFloaterIMPanel; class LLFriendObserver; -class LLFloaterIM; class LLIMMgr : public LLSingleton { @@ -131,6 +131,9 @@ public: void notifyNewIM(); void clearNewIMNotification(); + // automatically start a call once the session has initialized + void autoStartCallOnStartup(const LLUUID& session_id); + // IM received that you haven't seen yet BOOL getIMReceived() const; int getIMUnreadCount(); @@ -163,6 +166,7 @@ public: void clearPendingInvitation(const LLUUID& session_id); + void processAgentListUpdates(const LLUUID& session_id, const LLSD& body); LLSD getPendingAgentListUpdates(const LLUUID& session_id); void addPendingAgentListUpdates( const LLUUID& sessioN_id, @@ -178,6 +182,18 @@ public: // Returns true if group chat is ignored for the UUID, false if not bool getIgnoreGroup(const LLUUID& group_id) const; + /** + * Start call in a session + * @return false if voice channel doesn't exist + **/ + bool startCall(const LLUUID& session_id, LLVoiceChannel::EDirection direction = LLVoiceChannel::OUTGOING_CALL); + + /** + * End call in a session + * @return false if voice channel doesn't exist + **/ + bool endCall(const LLUUID& session_id); + private: // create a panel and update internal representation for // consistency. Returns the pointer, caller (the class instance diff --git a/indra/newview/llvoicecallhandler.cpp b/indra/newview/llvoicecallhandler.cpp new file mode 100644 index 000000000..0f68f7972 --- /dev/null +++ b/indra/newview/llvoicecallhandler.cpp @@ -0,0 +1,69 @@ + /** + * @file llvoicecallhandler.cpp + * @brief slapp to handle avatar to avatar voice call. + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" +#include "llcommandhandler.h" +#include "llavataractions.h" +//#include "llnotificationsutil.h" +//#include "llui.h" + +class LLVoiceCallAvatarHandler : public LLCommandHandler +{ +public: + // requires trusted browser to trigger + LLVoiceCallAvatarHandler() : LLCommandHandler("voicecallavatar", UNTRUSTED_THROTTLE) + { + } + + bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web) + { + /*if (!LLUI::sSettingGroups["config"]->getBOOL("EnableVoiceCall")) + { + LLNotificationsUtil::add("NoVoiceCall", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit")); + return true; + }*/ + + //Make sure we have some parameters + if (params.size() == 0) + { + return false; + } + + //Get the ID + LLUUID id; + if (!id.set( params[0], FALSE )) + { + return false; + } + + //instigate call with this avatar + LLAvatarActions::startCall( id ); + return true; + } +}; + +LLVoiceCallAvatarHandler gVoiceCallAvatarHandler; +