AudioEffect: prevent adding effect for unknown session on first io
Bug: 309578734
Test: add an effect chain on a music ouput (first) and enable.
Add another chain on another output.
Ensure chain on music output is not suspended.
Adding a chain on a different output may suspend chain on default output
First output is assigned when an effect is created, then may be moved once the
session is associated to its output.
It leads to suspend the chain of first output.
This CL fixes this bug by adding effect in orphan chains until track is
created.
Change-Id: I0e4989d941e77a3b50157cbce43e4c1975c4d8e8
Merged-In: I0e4989d941e77a3b50157cbce43e4c1975c4d8e8
Signed-off-by: François Gaffie <francois.gaffie@renault.com>
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index d1a09a4..c9ef69f 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -1662,12 +1662,12 @@
if (chain == 0) {
// create a new chain for this session
ALOGV("createEffect_l() new effect chain for session %d", sessionId);
- chain = IAfEffectChain::create(this, sessionId);
+ chain = IAfEffectChain::create(this, sessionId, mAfThreadCallback);
addEffectChain_l(chain);
chain->setStrategy(getStrategyForSession_l(sessionId));
chainCreated = true;
} else {
- effect = chain->getEffectFromDesc_l(desc);
+ effect = chain->getEffectFromDesc(desc);
}
ALOGV("createEffect_l() got effect %p on chain %p", effect.get(), chain.get());
@@ -1675,7 +1675,7 @@
if (effect == 0) {
effectId = mAfThreadCallback->nextUniqueId(AUDIO_UNIQUE_ID_USE_EFFECT);
// create a new effect module if none present in the chain
- lStatus = chain->createEffect_l(effect, desc, effectId, sessionId, pinned);
+ lStatus = chain->createEffect(effect, desc, effectId, sessionId, pinned);
if (lStatus != NO_ERROR) {
goto Exit;
}
@@ -1693,6 +1693,7 @@
const std::optional<media::AudioVibratorInfo> defaultVibratorInfo =
std::move(mAfThreadCallback->getDefaultVibratorInfo_l());
if (defaultVibratorInfo) {
+ audio_utils::lock_guard _cl(chain->mutex());
// Only set the vibrator info when it is a valid one.
effect->setVibratorInfo_l(*defaultVibratorInfo);
}
@@ -1714,7 +1715,7 @@
if (!probe && lStatus != NO_ERROR && lStatus != ALREADY_EXISTS) {
audio_utils::lock_guard _l(mutex());
if (effectCreated) {
- chain->removeEffect_l(effect);
+ chain->removeEffect(effect);
}
if (chainCreated) {
removeEffectChain_l(chain);
@@ -1815,7 +1816,7 @@
if (chain == 0) {
// create a new chain for this session
ALOGV("%s: new effect chain for session %d", __func__, sessionId);
- chain = IAfEffectChain::create(this, sessionId);
+ chain = IAfEffectChain::create(this, sessionId, mAfThreadCallback);
addEffectChain_l(chain);
chain->setStrategy(getStrategyForSession_l(sessionId));
chainCreated = true;
@@ -1830,7 +1831,7 @@
effect->setOffloaded_l(mType == OFFLOAD, mId);
- status_t status = chain->addEffect_l(effect);
+ status_t status = chain->addEffect(effect);
if (status != NO_ERROR) {
if (chainCreated) {
removeEffectChain_l(chain);
@@ -1857,7 +1858,7 @@
sp<IAfEffectChain> chain = effect->getCallback()->chain().promote();
if (chain != 0) {
// remove effect chain if removing last effect
- if (chain->removeEffect_l(effect, release) == 0) {
+ if (chain->removeEffect(effect, release) == 0) {
removeEffectChain_l(chain);
}
} else {
@@ -2897,7 +2898,7 @@
sp<IAfEffectChain> chain = getEffectChain_l(track->sessionId());
if (mHapticChannelMask != AUDIO_CHANNEL_NONE
&& ((track->channelMask() & AUDIO_CHANNEL_HAPTIC_ALL) != AUDIO_CHANNEL_NONE
- || (chain != nullptr && chain->containsHapticGeneratingEffect_l()))) {
+ || (chain != nullptr && chain->containsHapticGeneratingEffect()))) {
// Unlock due to VibratorService will lock for this call and will
// call Tracks.mute/unmute which also require thread's lock.
mutex().unlock();
@@ -4801,7 +4802,7 @@
}
if (mHapticChannelCount > 0 &&
((track->channelMask() & AUDIO_CHANNEL_HAPTIC_ALL) != AUDIO_CHANNEL_NONE
- || (chain != nullptr && chain->containsHapticGeneratingEffect_l()))) {
+ || (chain != nullptr && chain->containsHapticGeneratingEffect()))) {
mutex().unlock();
// Unlock due to VibratorService will lock for this call and will
// call Tracks.mute/unmute which also require thread's lock.