diff options
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/newview/llconversationmodel.cpp | 26 | ||||
| -rw-r--r-- | indra/newview/llfloaterimsessiontab.cpp | 41 | ||||
| -rw-r--r-- | indra/newview/llimview.cpp | 8 | ||||
| -rw-r--r-- | indra/newview/llvoicechannel.cpp | 12 | ||||
| -rw-r--r-- | indra/newview/llvoicevivox.cpp | 18 | 
5 files changed, 75 insertions, 30 deletions
| diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp index 4335168417..4cd85ac756 100644 --- a/indra/newview/llconversationmodel.cpp +++ b/indra/newview/llconversationmodel.cpp @@ -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();  } diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index dc64d09f9f..0ed84c381f 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -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); diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 014dd90406..d3f013c67c 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -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);      } diff --git a/indra/newview/llvoicechannel.cpp b/indra/newview/llvoicechannel.cpp index f6556b7128..8681411a98 100644 --- a/indra/newview/llvoicechannel.cpp +++ b/indra/newview/llvoicechannel.cpp @@ -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);      } diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index 3554933a52..1833aeb54f 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -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"]);  } | 
