void EffectChain::setEffectSuspendedAll_l(bool suspend) { sp desc; auto it = mSuspendedEffects.find((int)kKeyForSuspendAll); if (suspend) { if (it != mSuspendedEffects.end()) { desc = it->second; } else { desc = new SuspendedEffectDesc(); mSuspendedEffects[(int)kKeyForSuspendAll] = desc; ALOGV("setEffectSuspendedAll_l() add entry for 0"); } if (desc->mRefCount++ == 0) { std::vector> effects; getSuspendEligibleEffects(effects); for (const auto& effect : effects) { setEffectSuspended_l(&effect->desc().type, true); } } } else { if (it == mSuspendedEffects.end()) { return; } desc = it->second; if (desc->mRefCount <= 0) { ALOGW("setEffectSuspendedAll_l() restore refcount should not be 0 %d", desc->mRefCount); desc->mRefCount = 1; } if (--desc->mRefCount == 0) { std::vector types; for (const auto& [key, effectDesc] : mSuspendedEffects) { if (key == (int)kKeyForSuspendAll) { continue; } types.push_back(&effectDesc->mType); } for (const auto& type : types) { setEffectSuspended_l(type, false); } ALOGV("%s() remove entry for %08x", __func__, it->first); mSuspendedEffects.erase((int)kKeyForSuspendAll); } } } // The volume effect is used for automated tests only #ifndef OPENSL_ES_H_ static const effect_uuid_t SL_IID_VOLUME_ = { 0x09e8ede0, 0xddde, 0x11db, 0xb4f6, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } }; const effect_uuid_t * const SL_IID_VOLUME = &SL_IID_VOLUME_; #endif //OPENSL_ES_H_ /* static */ bool EffectChain::isEffectEligibleForBtNrecSuspend_l(const effect_uuid_t* type) { // Only NS and AEC are suspended when BtNRec is off if ((memcmp(type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0) || (memcmp(type, FX_IID_NS, sizeof(effect_uuid_t)) == 0)) { return true; } return false; } bool EffectChain::isEffectEligibleForSuspend(const effect_descriptor_t& desc) { // auxiliary effects and visualizer are never suspended on output mix if ((mSessionId == AUDIO_SESSION_OUTPUT_MIX) && (((desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) || (memcmp(&desc.type, SL_IID_VISUALIZATION, sizeof(effect_uuid_t)) == 0) || (memcmp(&desc.type, SL_IID_VOLUME, sizeof(effect_uuid_t)) == 0) || (memcmp(&desc.type, SL_IID_DYNAMICSPROCESSING, sizeof(effect_uuid_t)) == 0))) { return false; } return true; } void EffectChain::getSuspendEligibleEffects(std::vector>& effects) { effects.clear(); audio_utils::lock_guard _l(mutex()); for (size_t i = 0; i < mEffects.size(); i++) { if (isEffectEligibleForSuspend(mEffects[i]->desc())) { effects.push_back(mEffects[i]); } } } sp EffectChain::getEffectIfEnabled_l(const effect_uuid_t *type) { sp effect = getEffectFromType_l(type); return effect != 0 && effect->isEnabled() ? effect : 0; } void EffectChain::checkSuspendOnEffectEnabled_l(const sp& effect, bool enabled) { auto it = mSuspendedEffects.find(effect->desc().type.timeLow); if (enabled) { if (it == mSuspendedEffects.end()) { // if the effect is not suspend check if all effects are suspended it = mSuspendedEffects.find((int)kKeyForSuspendAll); if (it == mSuspendedEffects.end()) {