From d5e97617c661dd3518ef1caa6903867ad044df8d Mon Sep 17 00:00:00 2001 From: Mike Antipov Date: Mon, 1 Feb 2010 17:48:25 +0200 Subject: Fixed major bug EXT-4782 (Viewer crashes if end ad-hoc voice chat by 'End session' context commant of chiclet) - reason: indicator on ad-hoc chiclets is changed its speaker UUID that leads to registering the same instances several times in the SpeakingIndicatorManager. This leads to crash after instance is destroyed because the only one (specified by UUID in unregisterSpeakingIndicator()) is removed from the map. So, using stored deleted pointer leads to crash. See EXT-4782. - fix: prevent regestering the same instance of indicator by removing existing one in LLOutputMonitorCtrl::setSpeakerId. Also added check in SpeakingIndicatorManager to prevent such situation in the future with an appropriate warning & assert. --HG-- branch : product-engine --- indra/newview/lloutputmonitorctrl.cpp | 5 ++++ indra/newview/llspeakingindicatormanager.cpp | 41 +++++++++++++++++++++++++++- 2 files changed, 45 insertions(+), 1 deletion(-) (limited to 'indra/newview') diff --git a/indra/newview/lloutputmonitorctrl.cpp b/indra/newview/lloutputmonitorctrl.cpp index f816dc589d..388fdeea7a 100644 --- a/indra/newview/lloutputmonitorctrl.cpp +++ b/indra/newview/lloutputmonitorctrl.cpp @@ -251,6 +251,11 @@ void LLOutputMonitorCtrl::setSpeakerId(const LLUUID& speaker_id) { if (speaker_id.isNull() || speaker_id == mSpeakerId) return; + if (mSpeakerId.notNull()) + { + // Unregister previous registration to avoid crash. EXT-4782. + LLSpeakingIndicatorManager::unregisterSpeakingIndicator(mSpeakerId, this); + } mSpeakerId = speaker_id; LLSpeakingIndicatorManager::registerSpeakingIndicator(mSpeakerId, this); diff --git a/indra/newview/llspeakingindicatormanager.cpp b/indra/newview/llspeakingindicatormanager.cpp index 5e1d408e8d..d33c050ee4 100644 --- a/indra/newview/llspeakingindicatormanager.cpp +++ b/indra/newview/llspeakingindicatormanager.cpp @@ -113,6 +113,13 @@ private: */ void switchSpeakerIndicators(const speaker_ids_t& speakers_uuids, BOOL switch_on); + /** + * Ensures that passed instance of Speaking Indicator does not exist among registered ones. + * If yes, it will be removed. + */ + void ensureInstanceDoesNotExist(LLSpeakingIndicator* const speaking_indicator); + + /** * Multimap with all registered speaking indicators */ @@ -135,7 +142,11 @@ void SpeakingIndicatorManager::registerSpeakingIndicator(const LLUUID& speaker_i { // do not exclude agent's indicators. They should be processed in the same way as others. See EXT-3889. - LL_DEBUGS("SpeakingIndicator") << "Registering indicator: " << speaker_id << LL_ENDL; + LL_DEBUGS("SpeakingIndicator") << "Registering indicator: " << speaker_id << "|"<< speaking_indicator << LL_ENDL; + + + ensureInstanceDoesNotExist(speaking_indicator); + speaking_indicator_value_t value_type(speaker_id, speaking_indicator); mSpeakingIndicators.insert(value_type); @@ -148,12 +159,14 @@ void SpeakingIndicatorManager::registerSpeakingIndicator(const LLUUID& speaker_i void SpeakingIndicatorManager::unregisterSpeakingIndicator(const LLUUID& speaker_id, const LLSpeakingIndicator* const speaking_indicator) { + LL_DEBUGS("SpeakingIndicator") << "Unregistering indicator: " << speaker_id << "|"<< speaking_indicator << LL_ENDL; speaking_indicators_mmap_t::iterator it; it = mSpeakingIndicators.find(speaker_id); for (;it != mSpeakingIndicators.end(); ++it) { if (it->second == speaking_indicator) { + LL_DEBUGS("SpeakingIndicator") << "Unregistered." << LL_ENDL; mSpeakingIndicators.erase(it); break; } @@ -231,6 +244,32 @@ void SpeakingIndicatorManager::switchSpeakerIndicators(const speaker_ids_t& spea } } +void SpeakingIndicatorManager::ensureInstanceDoesNotExist(LLSpeakingIndicator* const speaking_indicator) +{ + LL_DEBUGS("SpeakingIndicator") << "Searching for an registered indicator instance: " << speaking_indicator << LL_ENDL; + speaking_indicators_mmap_t::iterator it = mSpeakingIndicators.begin(); + for (;it != mSpeakingIndicators.end(); ++it) + { + if (it->second == speaking_indicator) + { + LL_DEBUGS("SpeakingIndicator") << "Found" << LL_ENDL; + break; + } + } + + // It is possible with LLOutputMonitorCtrl the same instance of indicator is registered several + // times with different UUIDs. This leads to crash after instance is destroyed because the + // only one (specified by UUID in unregisterSpeakingIndicator()) is removed from the map. + // So, using stored deleted pointer leads to crash. See EXT-4782. + if (it != mSpeakingIndicators.end()) + { + llwarns << "The same instance of indicator has already been registered, removing it: " << it->first << "|"<< speaking_indicator << llendl; + llassert(it == mSpeakingIndicators.end()); + mSpeakingIndicators.erase(it); + } +} + + /************************************************************************/ /* LLSpeakingIndicatorManager namespace implementation */ /************************************************************************/ -- cgit v1.2.3 From 7bcba326b32e1aca678edfb4495d1e2d4d44cb71 Mon Sep 17 00:00:00 2001 From: Eugene Mutavchi Date: Mon, 1 Feb 2010 18:25:58 +0200 Subject: Fixed major bug EXT-4798 (Voice notifications steal keyboard focus by default) --HG-- branch : product-engine --- indra/newview/llimview.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'indra/newview') diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index b7d4db853e..db6b2041f8 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -1467,6 +1467,7 @@ LLCallDialog::LLCallDialog(const LLSD& payload) mPayload(payload), mLifetime(DEFAULT_LIFETIME) { + setAutoFocus(FALSE); } void LLCallDialog::getAllowedRect(LLRect& rect) @@ -1794,7 +1795,7 @@ BOOL LLIncomingCallDialog::postBuild() childSetAction("Accept", onAccept, this); childSetAction("Reject", onReject, this); childSetAction("Start IM", onStartIM, this); - childSetFocus("Accept"); + setDefaultBtn("Accept"); std::string notify_box_type = mPayload["notify_box_type"].asString(); if(notify_box_type != "VoiceInviteGroup" && notify_box_type != "VoiceInviteAdHoc") @@ -2424,7 +2425,7 @@ void LLIMMgr::inviteToSession( } else { - LLFloaterReg::showInstance("incoming_call", payload, TRUE); + LLFloaterReg::showInstance("incoming_call", payload, FALSE); } mPendingInvitations[session_id.asString()] = LLSD(); } @@ -2437,7 +2438,7 @@ void LLIMMgr::onInviteNameLookup(LLSD payload, const LLUUID& id, const std::stri std::string notify_box_type = payload["notify_box_type"].asString(); - LLFloaterReg::showInstance("incoming_call", payload, TRUE); + LLFloaterReg::showInstance("incoming_call", payload, FALSE); } //*TODO disconnects all sessions -- cgit v1.2.3 From a359db96eb0273bf67fe48bae2665ea65831cf67 Mon Sep 17 00:00:00 2001 From: Sergei Litovchuk Date: Mon, 1 Feb 2010 16:57:34 +0200 Subject: (EXT-2987) Parcel Characteristics icons aren't refreshed after changing restrictions - LLViewerParcelMgr refactoring. Changed parcel characteristics accessors to get selected parcel properties. --HG-- branch : product-engine --- indra/newview/lllocationinputctrl.cpp | 14 ++++++------ indra/newview/llpanelplaceprofile.cpp | 40 ++++++++++++++++------------------- indra/newview/llviewerparcelmgr.cpp | 36 ++++++++++++++++++------------- indra/newview/llviewerparcelmgr.h | 12 ++++++----- 4 files changed, 52 insertions(+), 50 deletions(-) (limited to 'indra/newview') diff --git a/indra/newview/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp index 0e93e28f2d..4f40a0a532 100644 --- a/indra/newview/lllocationinputctrl.cpp +++ b/indra/newview/lllocationinputctrl.cpp @@ -722,14 +722,12 @@ void LLLocationInputCtrl::refreshParcelIcons() } bool allow_buy = vpm->canAgentBuyParcel(current_parcel, false); - bool allow_voice = agent_region->isVoiceEnabled() && current_parcel->getParcelFlagAllowVoice(); - bool allow_fly = !agent_region->getBlockFly() && current_parcel->getAllowFly(); - bool allow_push = !agent_region->getRestrictPushObject() && !current_parcel->getRestrictPushObject(); - bool allow_build = current_parcel->getAllowModify(); // true when anyone is allowed to build. See EXT-4610. - bool allow_scripts = !(agent_region->getRegionFlags() & REGION_FLAGS_SKIP_SCRIPTS) && - !(agent_region->getRegionFlags() & REGION_FLAGS_ESTATE_SKIP_SCRIPTS) && - current_parcel->getAllowOtherScripts(); - bool allow_damage = agent_region->getAllowDamage() || current_parcel->getAllowDamage(); + bool allow_voice = vpm->allowAgentVoice(agent_region, current_parcel); + bool allow_fly = vpm->allowAgentFly(agent_region, current_parcel); + bool allow_push = vpm->allowAgentPush(agent_region, current_parcel); + bool allow_build = vpm->allowAgentBuild(current_parcel); // true when anyone is allowed to build. See EXT-4610. + bool allow_scripts = vpm->allowAgentScripts(agent_region, current_parcel); + bool allow_damage = vpm->allowAgentDamage(agent_region, current_parcel); // Most icons are "block this ability" mForSaleBtn->setVisible(allow_buy); diff --git a/indra/newview/llpanelplaceprofile.cpp b/indra/newview/llpanelplaceprofile.cpp index 9b31ef23a2..9e5f9da0ea 100644 --- a/indra/newview/llpanelplaceprofile.cpp +++ b/indra/newview/llpanelplaceprofile.cpp @@ -340,8 +340,10 @@ void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel, std::string on = getString("on"); std::string off = getString("off"); + LLViewerParcelMgr* vpm = LLViewerParcelMgr::getInstance(); + // Processing parcel characteristics - if (region->isVoiceEnabled() && parcel->getParcelFlagAllowVoice()) + if (vpm->allowAgentVoice(region, parcel)) { mVoiceIcon->setValue(icon_voice); mVoiceText->setText(on); @@ -352,7 +354,7 @@ void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel, mVoiceText->setText(off); } - if (!region->getBlockFly() && parcel->getAllowFly()) + if (vpm->allowAgentFly(region, parcel)) { mFlyIcon->setValue(icon_fly); mFlyText->setText(on); @@ -363,18 +365,18 @@ void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel, mFlyText->setText(off); } - if (region->getRestrictPushObject() || parcel->getRestrictPushObject()) + if (vpm->allowAgentPush(region, parcel)) { - mPushIcon->setValue(icon_push_no); - mPushText->setText(off); + mPushIcon->setValue(icon_push); + mPushText->setText(on); } else { - mPushIcon->setValue(icon_push); - mPushText->setText(on); + mPushIcon->setValue(icon_push_no); + mPushText->setText(off); } - if (parcel->getAllowModify()) + if (vpm->allowAgentBuild(parcel)) { mBuildIcon->setValue(icon_build); mBuildText->setText(on); @@ -385,20 +387,18 @@ void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel, mBuildText->setText(off); } - if ((region->getRegionFlags() & REGION_FLAGS_SKIP_SCRIPTS) || - (region->getRegionFlags() & REGION_FLAGS_ESTATE_SKIP_SCRIPTS) || - !parcel->getAllowOtherScripts()) + if (vpm->allowAgentScripts(region, parcel)) { - mScriptsIcon->setValue(icon_scripts_no); - mScriptsText->setText(off); + mScriptsIcon->setValue(icon_scripts); + mScriptsText->setText(on); } else { - mScriptsIcon->setValue(icon_scripts); - mScriptsText->setText(on); + mScriptsIcon->setValue(icon_scripts_no); + mScriptsText->setText(off); } - if (region->getAllowDamage() || parcel->getAllowDamage()) + if (vpm->allowAgentDamage(region, parcel)) { mDamageIcon->setValue(icon_damage); mDamageText->setText(on); @@ -461,12 +461,8 @@ void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel, S32 claim_price; S32 rent_price; F32 dwell; - BOOL for_sale = parcel->getForSale(); - LLViewerParcelMgr::getInstance()->getDisplayInfo(&area, - &claim_price, - &rent_price, - &for_sale, - &dwell); + BOOL for_sale; + vpm->getDisplayInfo(&area, &claim_price, &rent_price, &for_sale, &dwell); if (for_sale) { const LLUUID& auth_buyer_id = parcel->getAuthorizedBuyerID(); diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp index b85b42c710..7ec650629d 100644 --- a/indra/newview/llviewerparcelmgr.cpp +++ b/indra/newview/llviewerparcelmgr.cpp @@ -666,31 +666,38 @@ bool LLViewerParcelMgr::allowAgentBuild() const } } +// Return whether anyone can build on the given parcel +bool LLViewerParcelMgr::allowAgentBuild(const LLParcel* parcel) const +{ + return parcel->getAllowModify(); +} + bool LLViewerParcelMgr::allowAgentVoice() const { - LLViewerRegion* region = gAgent.getRegion(); + return allowAgentVoice(gAgent.getRegion(), mAgentParcel); +} + +bool LLViewerParcelMgr::allowAgentVoice(const LLViewerRegion* region, const LLParcel* parcel) const +{ return region && region->isVoiceEnabled() - && mAgentParcel && mAgentParcel->getParcelFlagAllowVoice(); + && parcel && parcel->getParcelFlagAllowVoice(); } -bool LLViewerParcelMgr::allowAgentFly() const +bool LLViewerParcelMgr::allowAgentFly(const LLViewerRegion* region, const LLParcel* parcel) const { - LLViewerRegion* region = gAgent.getRegion(); return region && !region->getBlockFly() - && mAgentParcel && mAgentParcel->getAllowFly(); + && parcel && parcel->getAllowFly(); } // Can the agent be pushed around by LLPushObject? -bool LLViewerParcelMgr::allowAgentPush() const +bool LLViewerParcelMgr::allowAgentPush(const LLViewerRegion* region, const LLParcel* parcel) const { - LLViewerRegion* region = gAgent.getRegion(); return region && !region->getRestrictPushObject() - && mAgentParcel && !mAgentParcel->getRestrictPushObject(); + && parcel && !parcel->getRestrictPushObject(); } -bool LLViewerParcelMgr::allowAgentScripts() const +bool LLViewerParcelMgr::allowAgentScripts(const LLViewerRegion* region, const LLParcel* parcel) const { - LLViewerRegion* region = gAgent.getRegion(); // *NOTE: This code does not take into account group-owned parcels // and the flag to allow group-owned scripted objects to run. // This mirrors the traditional menu bar parcel icon code, but is not @@ -698,15 +705,14 @@ bool LLViewerParcelMgr::allowAgentScripts() const return region && !(region->getRegionFlags() & REGION_FLAGS_SKIP_SCRIPTS) && !(region->getRegionFlags() & REGION_FLAGS_ESTATE_SKIP_SCRIPTS) - && mAgentParcel - && mAgentParcel->getAllowOtherScripts(); + && parcel + && parcel->getAllowOtherScripts(); } -bool LLViewerParcelMgr::allowAgentDamage() const +bool LLViewerParcelMgr::allowAgentDamage(const LLViewerRegion* region, const LLParcel* parcel) const { - LLViewerRegion* region = gAgent.getRegion(); return (region && region->getAllowDamage()) - || (mAgentParcel && mAgentParcel->getAllowDamage()); + || (parcel && parcel->getAllowDamage()); } BOOL LLViewerParcelMgr::isOwnedAt(const LLVector3d& pos_global) const diff --git a/indra/newview/llviewerparcelmgr.h b/indra/newview/llviewerparcelmgr.h index 379190789b..98be8e2c7b 100644 --- a/indra/newview/llviewerparcelmgr.h +++ b/indra/newview/llviewerparcelmgr.h @@ -171,26 +171,28 @@ public: // Can this agent build on the parcel he is on? // Used for parcel property icons in nav bar. bool allowAgentBuild() const; + bool allowAgentBuild(const LLParcel* parcel) const; // Can this agent speak on the parcel he is on? // Used for parcel property icons in nav bar. bool allowAgentVoice() const; - + bool allowAgentVoice(const LLViewerRegion* region, const LLParcel* parcel) const; + // Can this agent start flying on this parcel? // Used for parcel property icons in nav bar. - bool allowAgentFly() const; + bool allowAgentFly(const LLViewerRegion* region, const LLParcel* parcel) const; // Can this agent be pushed by llPushObject() on this parcel? // Used for parcel property icons in nav bar. - bool allowAgentPush() const; + bool allowAgentPush(const LLViewerRegion* region, const LLParcel* parcel) const; // Can scripts written by non-parcel-owners run on the agent's current // parcel? Used for parcel property icons in nav bar. - bool allowAgentScripts() const; + bool allowAgentScripts(const LLViewerRegion* region, const LLParcel* parcel) const; // Can the agent be damaged here? // Used for parcel property icons in nav bar. - bool allowAgentDamage() const; + bool allowAgentDamage(const LLViewerRegion* region, const LLParcel* parcel) const; F32 getHoverParcelWidth() const { return F32(mHoverEastNorth.mdV[VX] - mHoverWestSouth.mdV[VX]); } -- cgit v1.2.3