Merge pull request #1850 from secondlife/roxie/webrtc-voice-crash-fixes
Various crash fixes. ALso fixes an issue with adhoc/group calls on vivox regions.meow-7.2.2
commit
9bc3dfbdea
|
|
@ -357,22 +357,20 @@ void LLConversationItemSession::clearParticipants()
|
|||
|
||||
void LLConversationItemSession::clearAndDeparentModels()
|
||||
{
|
||||
std::for_each(mChildren.begin(), mChildren.end(),
|
||||
[](LLFolderViewModelItem* c)
|
||||
for (LLFolderViewModelItem* child : mChildren)
|
||||
{
|
||||
if (child->getNumRefs() == 0)
|
||||
{
|
||||
if (c->getNumRefs() == 0)
|
||||
{
|
||||
// LLConversationItemParticipant can be created but not assigned to any view,
|
||||
// it was waiting for an "add_participant" event to be processed
|
||||
delete c;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Model is still assigned to some view/widget
|
||||
c->setParent(NULL);
|
||||
}
|
||||
// LLConversationItemParticipant can be created but not assigned to any view,
|
||||
// it was waiting for an "add_participant" event to be processed
|
||||
delete child;
|
||||
}
|
||||
);
|
||||
else
|
||||
{
|
||||
// Model is still assigned to some view/widget
|
||||
child->setParent(NULL);
|
||||
}
|
||||
}
|
||||
mChildren.clear();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -102,6 +102,26 @@ LLFloaterIMSessionTab::LLFloaterIMSessionTab(const LLSD& session_id)
|
|||
LLFloaterIMSessionTab::~LLFloaterIMSessionTab()
|
||||
{
|
||||
delete mRefreshTimer;
|
||||
|
||||
LLFloaterIMContainer* im_container = LLFloaterIMContainer::findInstance();
|
||||
if (im_container)
|
||||
{
|
||||
LLParticipantList* session = dynamic_cast<LLParticipantList*>(im_container->getSessionModel(mSessionID));
|
||||
if (session)
|
||||
{
|
||||
for (const conversations_widgets_map::value_type& widget_pair : mConversationsWidgets)
|
||||
{
|
||||
LLFolderViewItem* widget = widget_pair.second;
|
||||
LLFolderViewModelItem* item_vmi = widget->getViewModelItem();
|
||||
if (item_vmi && item_vmi->getNumRefs() == 1)
|
||||
{
|
||||
// This is the last pointer, remove participant from session
|
||||
// before participant gets deleted on destroyView.
|
||||
session->removeChild(item_vmi);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
|
|
@ -663,6 +683,27 @@ void LLFloaterIMSessionTab::removeConversationViewParticipant(const LLUUID& part
|
|||
LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,participant_id);
|
||||
if (widget)
|
||||
{
|
||||
LLFolderViewModelItem* item_vmi = widget->getViewModelItem();
|
||||
if (item_vmi && item_vmi->getNumRefs() == 1)
|
||||
{
|
||||
// This is the last pointer, remove participant from session
|
||||
// before participant gets deleted on destroyView.
|
||||
//
|
||||
// Floater (widget) and participant's view can simultaneously
|
||||
// co-own the model, in which case view is responsible for
|
||||
// the deletion and floater is free to clear and recreate
|
||||
// the list, yet there are cases where only widget owns
|
||||
// the pointer so it should do the cleanup.
|
||||
// See "add_participant".
|
||||
//
|
||||
// Todo: If it keeps causing issues turn participants
|
||||
// into LLPointers in the session
|
||||
LLParticipantList* session = getParticipantList();
|
||||
if (session)
|
||||
{
|
||||
session->removeChild(item_vmi);
|
||||
}
|
||||
}
|
||||
widget->destroyView();
|
||||
}
|
||||
mConversationsWidgets.erase(participant_id);
|
||||
|
|
|
|||
|
|
@ -3413,11 +3413,11 @@ LLUUID LLIMMgr::addSession(
|
|||
((IM_NOTHING_SPECIAL == dialog) || (IM_SESSION_P2P_INVITE == dialog) || (IM_SESSION_CONFERENCE_START == dialog)) &&
|
||||
ids.size())
|
||||
{
|
||||
LLIMModel::LLIMSession* ad_hoc_found = LLIMModel::getInstance()->findAdHocIMSession(ids);
|
||||
if (ad_hoc_found)
|
||||
session = LLIMModel::getInstance()->findAdHocIMSession(ids);
|
||||
if (session)
|
||||
{
|
||||
new_session = false;
|
||||
session_id = ad_hoc_found->mSessionID;
|
||||
session_id = session->mSessionID;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3853,7 +3853,7 @@ bool LLIMMgr::startCall(const LLUUID& session_id, LLVoiceChannel::EDirection dir
|
|||
{
|
||||
LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(session_id);
|
||||
if (!voice_channel) return false;
|
||||
if (!voice_channel_info.isUndefined())
|
||||
if (voice_channel_info.isDefined() && voice_channel_info.isMap() && voice_channel_info.size() > 0)
|
||||
{
|
||||
voice_channel->setChannelInfo(voice_channel_info);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ void LLVoiceChannel::setChannelInfo(const LLSD &channelInfo)
|
|||
|
||||
if (mState == STATE_NO_CHANNEL_INFO)
|
||||
{
|
||||
if (mChannelInfo.isUndefined())
|
||||
if (mChannelInfo.isUndefined() || !mChannelInfo.isMap() || mChannelInfo.size() == 0)
|
||||
{
|
||||
LLNotificationsUtil::add("VoiceChannelJoinFailed", mNotifyArgs);
|
||||
LL_WARNS("Voice") << "Received empty channel info for channel " << mSessionName << LL_ENDL;
|
||||
|
|
@ -122,7 +122,7 @@ void LLVoiceChannel::onChange(EStatusType type, const LLSD& channelInfo, bool pr
|
|||
{
|
||||
LL_DEBUGS("Voice") << "Incoming channel info: " << channelInfo << LL_ENDL;
|
||||
LL_DEBUGS("Voice") << "Current channel info: " << mChannelInfo << LL_ENDL;
|
||||
if (mChannelInfo.isUndefined())
|
||||
if (mChannelInfo.isUndefined() || (mChannelInfo.isMap() && mChannelInfo.size() == 0))
|
||||
{
|
||||
mChannelInfo = channelInfo;
|
||||
}
|
||||
|
|
@ -477,7 +477,7 @@ void LLVoiceChannelGroup::setChannelInfo(const LLSD& channelInfo)
|
|||
|
||||
if (mState == STATE_NO_CHANNEL_INFO)
|
||||
{
|
||||
if(!mChannelInfo.isUndefined())
|
||||
if(mChannelInfo.isDefined() && mChannelInfo.isMap())
|
||||
{
|
||||
setState(STATE_READY);
|
||||
|
||||
|
|
@ -676,9 +676,9 @@ void LLVoiceChannelProximal::activate()
|
|||
// we're connected to a non-spatial channel, so disconnect.
|
||||
LLVoiceClient::getInstance()->leaveNonSpatialChannel();
|
||||
}
|
||||
|
||||
LLVoiceClient::getInstance()->activateSpatialChannel(true);
|
||||
LLVoiceChannel::activate();
|
||||
|
||||
}
|
||||
|
||||
void LLVoiceChannelProximal::onChange(EStatusType type, const LLSD& channelInfo, bool proximal)
|
||||
|
|
@ -751,7 +751,7 @@ void LLVoiceChannelProximal::deactivate()
|
|||
{
|
||||
setState(STATE_HUNG_UP);
|
||||
}
|
||||
|
||||
LLVoiceClient::getInstance()->removeObserver(this);
|
||||
LLVoiceClient::getInstance()->activateSpatialChannel(false);
|
||||
}
|
||||
|
||||
|
|
@ -907,7 +907,7 @@ void LLVoiceChannelP2P::setChannelInfo(const LLSD& channel_info)
|
|||
}
|
||||
|
||||
mReceivedCall = TRUE;
|
||||
if (!channel_info.isUndefined())
|
||||
if (channel_info.isDefined() && channel_info.isMap())
|
||||
{
|
||||
mIncomingCallInterface = LLVoiceClient::getInstance()->getIncomingCallInterface(channel_info);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5105,25 +5105,31 @@ void LLVivoxVoiceClient::processChannels(bool process)
|
|||
|
||||
bool LLVivoxVoiceClient::isCurrentChannel(const LLSD &channelInfo)
|
||||
{
|
||||
if (!mProcessChannels || (channelInfo["voice_server_type"].asString() != VIVOX_VOICE_SERVER_TYPE))
|
||||
if (!mProcessChannels || (channelInfo.has("voice_server_type") && channelInfo["voice_server_type"].asString() != VIVOX_VOICE_SERVER_TYPE))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (mAudioSession)
|
||||
// favor the next audio session, as that's the one we're bringing up.
|
||||
sessionStatePtr_t session = mNextAudioSession;
|
||||
if (!session)
|
||||
{
|
||||
session = mAudioSession;
|
||||
}
|
||||
if (session)
|
||||
{
|
||||
if (!channelInfo["session_handle"].asString().empty())
|
||||
{
|
||||
return mAudioSession->mHandle == channelInfo["session_handle"].asString();
|
||||
return session->mHandle == channelInfo["session_handle"].asString();
|
||||
}
|
||||
return channelInfo["channel_uri"].asString() == mAudioSession->mSIPURI;
|
||||
return channelInfo["channel_uri"].asString() == session->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"]) &&
|
||||
return (!channelInfo1.has("voice_server_type") || (channelInfo1["voice_server_type"] == VIVOX_VOICE_SERVER_TYPE)) &&
|
||||
(!channelInfo2.has("voice_server_type") || (channelInfo2["voice_server_type"] == VIVOX_VOICE_SERVER_TYPE)) &&
|
||||
(channelInfo1["channel_uri"] == channelInfo2["channel_uri"]);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue