diff options
| author | Monroe Williams <monroe@lindenlab.com> | 2009-03-19 19:18:07 +0000 | 
|---|---|---|
| committer | Monroe Williams <monroe@lindenlab.com> | 2009-03-19 19:18:07 +0000 | 
| commit | 5dfd435872e36445dcc82f99443dfc5a7ee0805a (patch) | |
| tree | 09c2c5697c88ebc3fff3be1e15de4a294d1acad1 | |
| parent | 733f7d212ff7e1befcdbcecca1e94e2ce9e0412a (diff) | |
svn merge -r 114639:114640 svn+ssh://svn.lindenlab.com/svn/linden/branches/qar-1361
Merging in QAR-1361.
| -rw-r--r-- | indra/newview/llimpanel.cpp | 24 | ||||
| -rw-r--r-- | indra/newview/llimpanel.h | 4 | ||||
| -rw-r--r-- | indra/newview/llvoiceclient.cpp | 240 | ||||
| -rw-r--r-- | indra/newview/llvoiceclient.h | 20 | ||||
| -rw-r--r-- | install.xml | 12 | 
5 files changed, 265 insertions, 35 deletions
| diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp index f3943345c7..fcebfa7053 100644 --- a/indra/newview/llimpanel.cpp +++ b/indra/newview/llimpanel.cpp @@ -1120,6 +1120,9 @@ LLFloaterIMPanel::LLFloaterIMPanel(  	mSentTypingState(TRUE),  	mShowSpeakersOnConnect(TRUE),  	mAutoConnect(FALSE), +	mTextIMPossible(TRUE), +	mProfileButtonEnabled(TRUE), +	mCallBackEnabled(TRUE),  	mSpeakers(NULL),  	mSpeakerPanel(NULL),  	mFirstKeystrokeTimer(), @@ -1165,7 +1168,13 @@ void LLFloaterIMPanel::init(const std::string& session_label)  		break;  	// just received text from another user  	case IM_NOTHING_SPECIAL: +  		xml_filename = "floater_instant_message.xml"; +		 +		mTextIMPossible = LLVoiceClient::getInstance()->isSessionTextIMPossible(mSessionUUID); +		mProfileButtonEnabled = LLVoiceClient::getInstance()->isParticipantAvatar(mSessionUUID); +		mCallBackEnabled = LLVoiceClient::getInstance()->isSessionCallBackPossible(mSessionUUID); +		  		mVoiceChannel = new LLVoiceChannelP2P(mSessionUUID, mSessionLabel, mOtherParticipantUUID);  		break;  	default: @@ -1297,6 +1306,11 @@ BOOL LLFloaterIMPanel::postBuild()  		{  			childSetEnabled("profile_btn", FALSE);  		} +		 +		if(!mProfileButtonEnabled) +		{ +			childSetEnabled("profile_callee_btn", FALSE); +		}  		sTitleString = getString("title_string");  		sTypingStartString = getString("typing_start_string"); @@ -1365,7 +1379,8 @@ void LLFloaterIMPanel::draw()  	BOOL enable_connect = (region && region->getCapability("ChatSessionRequest") != "")  					  && mSessionInitialized -					  && LLVoiceClient::voiceEnabled(); +					  && LLVoiceClient::voiceEnabled() +					  && mCallBackEnabled;  	// hide/show start call and end call buttons  	childSetVisible("end_call_btn", LLVoiceClient::voiceEnabled() && mVoiceChannel->getState() >= LLVoiceChannel::STATE_CALL_STARTED); @@ -1374,7 +1389,12 @@ void LLFloaterIMPanel::draw()  	childSetEnabled("send_btn", !childGetValue("chat_editor").asString().empty());  	LLPointer<LLSpeaker> self_speaker = mSpeakers->findSpeaker(gAgent.getID()); -	if (self_speaker.notNull() && self_speaker->mModeratorMutedText) +	if(!mTextIMPossible) +	{ +		mInputEditor->setEnabled(FALSE); +		mInputEditor->setLabel(getString("unavailable_text_label")); +	} +	else if (self_speaker.notNull() && self_speaker->mModeratorMutedText)  	{  		mInputEditor->setEnabled(FALSE);  		mInputEditor->setLabel(getString("muted_text_label")); diff --git a/indra/newview/llimpanel.h b/indra/newview/llimpanel.h index e54cec56c7..8b3ca202c7 100644 --- a/indra/newview/llimpanel.h +++ b/indra/newview/llimpanel.h @@ -343,6 +343,10 @@ private:  	BOOL mShowSpeakersOnConnect;  	BOOL mAutoConnect; +	 +	BOOL mTextIMPossible; +	BOOL mProfileButtonEnabled; +	BOOL mCallBackEnabled;  	LLIMSpeakerMgr* mSpeakers;  	LLPanelActiveSpeakers* mSpeakerPanel; diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index 3bcc0af7d5..94407ed08c 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -844,6 +844,16 @@ void LLVivoxProtocolParser::processResponse(std::string tag)  			*/  			// We don't need to process this, but we also shouldn't warn on it, since that confuses people.  		} +		 +		else if (!stricmp(eventTypeCstr, "SessionGroupRemovedEvent"))   +		{ +			/* +			<Event type="SessionGroupRemovedEvent"> +				<SessionGroupHandle>c1_m1000xFnPP04IpREWNkuw1cOXlhw==_sg0</SessionGroupHandle> +			</Event> +			*/ +			// We don't need to process this, but we also shouldn't warn on it, since that confuses people. +		}  		else  		{  			LL_WARNS("VivoxProtocolParser") << "Unknown event type " << eventTypeString << LL_ENDL; @@ -1560,20 +1570,27 @@ void LLVoiceClient::stateMachine()  			std::string regionName = region->getName();  			std::string capURI = region->getCapability("ParcelVoiceInfoRequest"); -//			LL_DEBUGS("Voice") << "Region name = \"" << regionName <<"\", " << "parcel local ID = " << parcelLocalID << LL_ENDL; +//			LL_DEBUGS("Voice") << "Region name = \"" << regionName << "\", parcel local ID = " << parcelLocalID << ", cap URI = \"" << capURI << "\"" << LL_ENDL;  			// The region name starts out empty and gets filled in later.    			// Also, the cap gets filled in a short time after the region cross, but a little too late for our purposes.  			// If either is empty, wait for the next time around. -			if(!regionName.empty() && !capURI.empty()) +			if(!regionName.empty())  			{ -				if((parcelLocalID != mCurrentParcelLocalID) || (regionName != mCurrentRegionName)) +				if(!capURI.empty())  				{ -					// We have changed parcels.  Initiate a parcel channel lookup. -					mCurrentParcelLocalID = parcelLocalID; -					mCurrentRegionName = regionName; -					 -					parcelChanged(); +					if((parcelLocalID != mCurrentParcelLocalID) || (regionName != mCurrentRegionName)) +					{ +						// We have changed parcels.  Initiate a parcel channel lookup. +						mCurrentParcelLocalID = parcelLocalID; +						mCurrentRegionName = regionName; +						 +						parcelChanged(); +					} +				} +				else +				{ +					LL_WARNS("Voice") << "region doesn't have ParcelVoiceInfoRequest capability.  This is normal for a short time after teleporting, but bad if it persists for very long." << LL_ENDL;  				}  			}  		} @@ -1840,6 +1857,10 @@ void LLVoiceClient::stateMachine()  						}  						setState(stateConnectorStart);  					} +					else +					{ +						LL_WARNS("Voice") << "region doesn't have ProvisionVoiceAccountRequest capability!" << LL_ENDL; +					}  				}  			}  		break; @@ -2308,12 +2329,27 @@ void LLVoiceClient::stateMachine()  		//MARK: stateLoggingOut  		case stateLoggingOut:			// waiting for logout response -			// The handler for the Account.Logout response will transition from here to stateLoggedOut. +			// The handler for the AccountLoginStateChangeEvent will transition from here to stateLoggedOut.  		break; +		  		//MARK: stateLoggedOut  		case stateLoggedOut:			// logout response received -			// shut down the connector -			connectorShutdown(); +			 +			// Once we're logged out, all these things are invalid. +			mAccountHandle.clear(); +			deleteAllSessions(); +			deleteAllBuddies(); + +			if(mVoiceEnabled && !mRelogRequested) +			{ +				// User was logged out, but wants to be logged in.  Send a new login request. +				setState(stateNeedsLogin); +			} +			else +			{ +				// shut down the connector +				connectorShutdown(); +			}  		break;  		//MARK: stateConnectorStopping @@ -2332,6 +2368,10 @@ void LLVoiceClient::stateMachine()  		break;  		//MARK: stateConnectorFailedWaiting  		case stateConnectorFailedWaiting: +			if(!mVoiceEnabled) +			{ +				setState(stateDisableCleanup); +			}  		break;  		//MARK: stateLoginFailed @@ -2340,7 +2380,10 @@ void LLVoiceClient::stateMachine()  		break;  		//MARK: stateLoginFailedWaiting  		case stateLoginFailedWaiting: -			// No way to recover from these.  Yet. +			if(!mVoiceEnabled) +			{ +				setState(stateDisableCleanup); +			}  		break;  		//MARK: stateJoinSessionFailed @@ -2689,6 +2732,19 @@ void LLVoiceClient::sessionTerminateSendMessage(sessionState *session)  	writeString(stream.str());  } +void LLVoiceClient::sessionGroupTerminateSendMessage(sessionState *session) +{ +	std::ostringstream stream; +	 +	LL_DEBUGS("Voice") << "Sending SessionGroup.Terminate with handle " << session->mGroupHandle << LL_ENDL;	 +	stream +	<< "<Request requestId=\"" << mCommandCookie++ << "\" action=\"SessionGroup.Terminate.1\">" +		<< "<SessionGroupHandle>" << session->mGroupHandle << "</SessionGroupHandle>" +	<< "</Request>\n\n\n"; +	 +	writeString(stream.str()); +} +  void LLVoiceClient::sessionMediaDisconnectSendMessage(sessionState *session)  {  	std::ostringstream stream; @@ -3227,14 +3283,23 @@ void LLVoiceClient::sendPositionalUpdate(void)  				// Can't set volume/mute for yourself  				if(!p->mIsSelf)  				{ -					int volume = p->mUserVolume; +					int volume = 56; // nominal default value  					bool mute = p->mOnMuteList; +					 +					if(p->mUserVolume != -1) +					{ +						// scale from user volume in the range 0-400 (with 100 as "normal") to vivox volume in the range 0-100 (with 56 as "normal") +						if(p->mUserVolume < 100) +							volume = (p->mUserVolume * 56) / 100; +						else +							volume = (((p->mUserVolume - 100) * (100 - 56)) / 300) + 56; +					} +					else if(p->mVolume != -1) +					{ +						// Use the previously reported internal volume (comes in with a ParticipantUpdatedEvent) +						volume = p->mVolume; +					} -					// SLIM SDK: scale volume from 0-400 (with 100 as "normal") to 0-100 (with 56 as "normal") -					if(volume < 100) -						volume = (volume * 56) / 100; -					else -						volume = (((volume - 100) * (100 - 56)) / 300) + 56;  					if(mute)  					{ @@ -3813,11 +3878,6 @@ void LLVoiceClient::logoutResponse(int statusCode, std::string &statusString)  		LL_WARNS("Voice") << "Account.Logout response failure: " << statusString << LL_ENDL;  		// Should this ever fail?  do we care if it does?  	} -	 -	if(getState() == stateLoggingOut) -	{ -		setState(stateLoggedOut); -	}  }  void LLVoiceClient::connectorShutdownResponse(int statusCode, std::string &statusString) @@ -3990,6 +4050,10 @@ void LLVoiceClient::sessionRemovedEvent(  		// This message invalidates the session's handle.  Set it to empty.  		setSessionHandle(session); +		// This also means that the session's session group is now empty. +		// Terminate the session group so it doesn't leak. +		sessionGroupTerminateSendMessage(session); +		  		// Reset the media state (we now have no info)  		session->mMediaStreamState = streamStateUnknown;  		session->mTextStreamState = streamStateUnknown; @@ -4131,6 +4195,16 @@ void LLVoiceClient::accountLoginStateChangeEvent(  			setState(stateLoggedIn);  		}  		break; + +		case 3: +			// The user is in the process of logging out. +			setState(stateLoggingOut); +		break; + +		case 0: +			// The user has been logged out.   +			setState(stateLoggedOut); +		break;  		default:  			//Used to be a commented out warning @@ -4756,9 +4830,9 @@ LLVoiceClient::participantState::participantState(const std::string &uri) :  	 mIsModeratorMuted(false),   	 mLastSpokeTimestamp(0.f),   	 mPower(0.f),  -	 mVolume(0),  +	 mVolume(-1),   	 mOnMuteList(false),  -	 mUserVolume(100),  +	 mUserVolume(-1),   	 mVolumeDirty(false),   	 mAvatarIDValid(false),  	 mIsSelf(false) @@ -4843,6 +4917,11 @@ bool LLVoiceClient::participantState::updateMuteState()  	return result;  } +bool LLVoiceClient::participantState::isAvatar() +{ +	return mAvatarIDValid; +} +  void LLVoiceClient::sessionState::removeParticipant(LLVoiceClient::participantState *participant)  {  	if(participant) @@ -5276,6 +5355,66 @@ bool LLVoiceClient::isOnlineSIP(const LLUUID &id)  	return result;  } +// Returns true if the indicated participant in the current audio session is really an SL avatar. +// Currently this will be false only for PSTN callers into group chats, and PSTN p2p calls. +bool LLVoiceClient::isParticipantAvatar(const LLUUID &id) +{ +	bool result = true;  +	sessionState *session = findSession(id); +	 +	if(session != NULL) +	{ +		// this is a p2p session with the indicated caller, or the session with the specified UUID. +		if(session->mSynthesizedCallerID) +			result = false; +	} +	else +	{ +		// Didn't find a matching session -- check the current audio session for a matching participant +		if(mAudioSession != NULL) +		{ +			participantState *participant = findParticipantByID(id); +			if(participant != NULL) +			{ +				result = participant->isAvatar(); +			} +		} +	} +	 +	return result; +} + +// 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.		 +bool LLVoiceClient::isSessionCallBackPossible(const LLUUID &session_id) +{ +	bool result = true;  +	sessionState *session = findSession(session_id); +	 +	if(session != NULL) +	{ +		result = session->isCallBackPossible(); +	} +	 +	return result; +} + +// Returns true if the session can accepte text IM's. +// Currently this will be false only for PSTN P2P calls. +bool LLVoiceClient::isSessionTextIMPossible(const LLUUID &session_id) +{ +	bool result = true;  +	sessionState *session = findSession(session_id); +	 +	if(session != NULL) +	{ +		result = session->isTextIMPossible(); +	} +	 +	return result; +} +		 +  void LLVoiceClient::declineInvite(std::string &sessionHandle)  {  	sessionState *session = findSession(sessionHandle); @@ -5928,10 +6067,42 @@ F32 LLVoiceClient::getUserVolume(const LLUUID& id)  	participantState *participant = findParticipantByID(id);  	if(participant)  	{ -		S32 ires = participant->mUserVolume; // 0-400 +		S32 ires = 100; // nominal default volume +		 +		if(participant->mIsSelf) +		{ +			// Always make it look like the user's own volume is set at the default. +		} +		else if(participant->mUserVolume != -1) +		{ +			// Use the internal volume +			ires = participant->mUserVolume; +			 +			// Enable this when debugging voice slider issues.  It's way to spammy even for debug-level logging. +//			LL_DEBUGS("Voice") << "mapping from mUserVolume " << ires << LL_ENDL; +		} +		else if(participant->mVolume != -1) +		{ +			// Map backwards from vivox volume  + +			// Enable this when debugging voice slider issues.  It's way to spammy even for debug-level logging. +//			LL_DEBUGS("Voice") << "mapping from mVolume " << participant->mVolume << LL_ENDL; + +			if(participant->mVolume < 56) +			{ +				ires = (participant->mVolume * 100) / 56; +			} +			else +			{ +				ires = (((participant->mVolume - 56) * 300) / (100 - 56)) + 100; +			} +		}  		result = sqrtf(((F32)ires) / 400.f);  	} +	// Enable this when debugging voice slider issues.  It's way to spammy even for debug-level logging. +//	LL_DEBUGS("Voice") << "returning " << result << LL_ENDL; +  	return result;  } @@ -6095,6 +6266,21 @@ LLVoiceClient::sessionState::~sessionState()  	removeAllParticipants();  } +bool LLVoiceClient::sessionState::isCallBackPossible() +{ +	// This may change to be explicitly specified by vivox in the future... +	// Currently, only PSTN P2P calls cannot be returned. +	// Conveniently, this is also the only case where we synthesize a caller UUID. +	return !mSynthesizedCallerID; +} + +bool LLVoiceClient::sessionState::isTextIMPossible() +{ +	// This may change to be explicitly specified by vivox in the future... +	return !mSynthesizedCallerID; +} + +  LLVoiceClient::sessionIterator LLVoiceClient::sessionsBegin(void)  {  	return mSessions.begin(); @@ -6141,7 +6327,7 @@ LLVoiceClient::sessionState *LLVoiceClient::findSession(const LLUUID &participan  	for(sessionIterator iter = sessionsBegin(); iter != sessionsEnd(); iter++)  	{  		sessionState *session = *iter; -		if(session->mCallerID == participant_id) +		if((session->mCallerID == participant_id) || (session->mIMSessionID == participant_id))  		{  			result = session;  			break; diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h index 43bbc8e29c..cfc336b27d 100644 --- a/indra/newview/llvoiceclient.h +++ b/indra/newview/llvoiceclient.h @@ -255,6 +255,7 @@ static	void updatePosition(void);  			participantState(const std::string &uri);  			bool updateMuteState(); +			bool isAvatar();  			std::string mURI;  			LLUUID mAvatarID; @@ -301,6 +302,9 @@ static	void updatePosition(void);  			participantState *findParticipant(const std::string &uri);  			participantState *findParticipantByID(const LLUUID& id); +			bool isCallBackPossible(); +			bool isTextIMPossible(); +  			std::string mHandle;  			std::string mGroupHandle;  			std::string mSIPURI; @@ -434,6 +438,7 @@ static	void updatePosition(void);  		void sessionMediaConnectSendMessage(sessionState *session);		// just joins the audio session  		void sessionTextConnectSendMessage(sessionState *session);		// just joins the text session  		void sessionTerminateSendMessage(sessionState *session); +		void sessionGroupTerminateSendMessage(sessionState *session);  		void sessionMediaDisconnectSendMessage(sessionState *session);  		void sessionTextDisconnectSendMessage(sessionState *session); @@ -496,6 +501,21 @@ static	void updatePosition(void);  		// Returns true if the indicated user is online via SIP presence according to SLVoice.  		// Note that we only get SIP presence data for other users that are in our vivox buddy list.  		bool isOnlineSIP(const LLUUID &id); + +		// Returns true if the indicated participant is really an SL avatar. +		// This should be used to control the state of the "profile" button. +		// Currently this will be false only for PSTN callers into group chats, and PSTN p2p calls. +		bool isParticipantAvatar(const LLUUID &id); +		 +		// 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.		 +		// NOTE: this will return true if the session can't be found.  +		bool isSessionCallBackPossible(const LLUUID &session_id); +		 +		// Returns true if the session can accepte text IM's. +		// Currently this will be false only for PSTN P2P calls. +		// NOTE: this will return true if the session can't be found.  +		bool isSessionTextIMPossible(const LLUUID &session_id);  	private: diff --git a/install.xml b/install.xml index b60fc7494b..b4941bd3e2 100644 --- a/install.xml +++ b/install.xml @@ -1193,23 +1193,23 @@ anguage Infrstructure (CLI) international standard</string>            <key>darwin</key>            <map>              <key>md5sum</key> -            <string>352eae0cd76bb561da7b4183fc5a2857</string> +            <string>8675b5eedef038b514338b17f0e55961</string>              <key>url</key> -            <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/vivox-2.1.3010.6151-darwin-20090218.tar.bz2</uri> +            <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/vivox-2.1.3010.6270-darwin-20090309.tar.bz2</uri>            </map>            <key>linux</key>            <map>              <key>md5sum</key> -            <string>2279e1637568a837d9a4971cd27ed5f7</string> +            <string>01573510dce7f380f44e561ef2f3dd9f</string>              <key>url</key> -            <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/vivox-2.1.3010.6151-linux-20090218.tar.bz2</uri> +            <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/vivox-2.1.3010.6270-linux-20090309.tar.bz2</uri>            </map>            <key>windows</key>            <map>              <key>md5sum</key> -            <string>311bedab0abbd3a0ddf07216711af0ea</string> +            <string>752daa90e07c05202d1f76980cb955eb</string>              <key>url</key> -            <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/vivox-2.1.3010.6151-windows-20090218.tar.bz2</uri> +            <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/vivox-2.1.3010.6270-windows-20090309.tar.bz2</uri>            </map>          </map>        </map> | 
