Revert "Revert "AudioEffect: prevent adding effect for unknown s..."
Revert submission 26624467-revert-25712917-SEPJYAPZTA
Reason for revert: b/330202134 fixed with ag/26627359
Reverted changes: /q/submissionid:26624467-revert-25712917-SEPJYAPZTA
Change-Id: I2ce880dea862df1b29a67893d60a9c98c4c4eb46
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 01f55dd..7ecca4f 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1079,6 +1079,7 @@
client = registerPid(clientPid);
IAfPlaybackThread* effectThread = nullptr;
+ sp<IAfEffectChain> effectChain = nullptr;
// check if an effect chain with the same session ID is present on another
// output thread and move it here.
for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
@@ -1091,6 +1092,10 @@
}
}
}
+ // Check if an orphan effect chain exists for this session
+ if (effectThread == nullptr) {
+ effectChain = getOrphanEffectChain_l(sessionId);
+ }
ALOGV("createTrack() sessionId: %d", sessionId);
output.sampleRate = input.config.sample_rate;
@@ -1135,6 +1140,13 @@
effectIds = thread->getEffectIds_l(sessionId);
}
}
+ if (effectChain != nullptr) {
+ if (moveEffectChain_ll(sessionId, nullptr, thread, effectChain.get())
+ == NO_ERROR) {
+ effectThreadId = thread->id();
+ effectIds = thread->getEffectIds_l(sessionId);
+ }
+ }
}
// Look for sync events awaiting for a session to be used.
@@ -4222,8 +4234,9 @@
// before creating the AudioEffect or the io handle must be specified.
//
// Detect if the effect is created after an AudioRecord is destroyed.
- if ((sessionId != AUDIO_SESSION_OUTPUT_MIX) &&
- getOrphanEffectChain_l(sessionId).get() != nullptr) {
+ if (sessionId != AUDIO_SESSION_OUTPUT_MIX
+ && ((descOut.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_PRE_PROC)
+ && getOrphanEffectChain_l(sessionId).get() != nullptr) {
ALOGE("%s: effect %s with no specified io handle is denied because the AudioRecord"
" for session %d no longer exists",
__func__, descOut.name, sessionId);
@@ -4234,11 +4247,27 @@
// Legacy handling of creating an effect on an expired or made-up
// session id. We think that it is a Playback effect.
//
- // If no output thread contains the requested session ID, default to
- // first output. The effect chain will be moved to the correct output
- // thread when a track with the same session ID is created
- if (io == AUDIO_IO_HANDLE_NONE && mPlaybackThreads.size() > 0) {
- io = mPlaybackThreads.keyAt(0);
+ // If no output thread contains the requested session ID, park the effect to
+ // the orphan chains. The effect chain will be moved to the correct output
+ // thread when a track with the same session ID is created.
+ if (io == AUDIO_IO_HANDLE_NONE) {
+ if (probe) {
+ // In probe mode, as no compatible thread found, exit with error.
+ lStatus = BAD_VALUE;
+ goto Exit;
+ }
+ ALOGV("%s() got io %d for effect %s", __func__, io, descOut.name);
+ sp<Client> client = registerPid(currentPid);
+ bool pinned = !audio_is_global_session(sessionId) && isSessionAcquired_l(sessionId);
+ handle = createOrphanEffect_l(client, effectClient, priority, sessionId,
+ &descOut, &enabledOut, &lStatus, pinned,
+ request.notifyFramesProcessed);
+ if (lStatus != NO_ERROR && lStatus != ALREADY_EXISTS) {
+ // remove local strong reference to Client with clientMutex() held
+ audio_utils::lock_guard _cl(clientMutex());
+ client.clear();
+ }
+ goto Register;
}
ALOGV("createEffect() got io %d for effect %s", io, descOut.name);
} else if (checkPlaybackThread_l(io) != nullptr
@@ -4356,6 +4385,78 @@
return lStatus;
}
+sp<IAfEffectHandle> AudioFlinger::createOrphanEffect_l(
+ const sp<Client>& client,
+ const sp<IEffectClient>& effectClient,
+ int32_t priority,
+ audio_session_t sessionId,
+ effect_descriptor_t *desc,
+ int *enabled,
+ status_t *status,
+ bool pinned,
+ bool notifyFramesProcessed)
+{
+ ALOGV("%s effectClient %p, priority %d, sessionId %d, factory %p",
+ __func__, effectClient.get(), priority, sessionId, mEffectsFactoryHal.get());
+
+ // Check if an orphan effect chain exists for this session or create new chain for this session
+ sp<IAfEffectModule> effect;
+ sp<IAfEffectChain> chain = getOrphanEffectChain_l(sessionId);
+ bool chainCreated = false;
+ if (chain == nullptr) {
+ chain = IAfEffectChain::create(/* ThreadBase= */ nullptr, sessionId, this);
+ chainCreated = true;
+ } else {
+ effect = chain->getEffectFromDesc(desc);
+ }
+ bool effectCreated = false;
+ if (effect == nullptr) {
+ audio_unique_id_t effectId = nextUniqueId(AUDIO_UNIQUE_ID_USE_EFFECT);
+ // create a new effect module if none present in the chain
+ status_t llStatus =
+ chain->createEffect(effect, desc, effectId, sessionId, pinned);
+ if (llStatus != NO_ERROR) {
+ *status = llStatus;
+ return nullptr;
+ }
+ effect->setMode(getMode());
+
+ if (effect->isHapticGenerator()) {
+ // TODO(b/184194057): Use the vibrator information from the vibrator that will be used
+ // for the HapticGenerator.
+ const std::optional<media::AudioVibratorInfo> defaultVibratorInfo =
+ std::move(getDefaultVibratorInfo_l());
+ if (defaultVibratorInfo) {
+ // Only set the vibrator info when it is a valid one.
+ audio_utils::lock_guard _cl(chain->mutex());
+ effect->setVibratorInfo_l(*defaultVibratorInfo);
+ }
+ }
+ effectCreated = true;
+ }
+ // create effect handle and connect it to effect module
+ sp<IAfEffectHandle> handle =
+ IAfEffectHandle::create(effect, client, effectClient, priority, notifyFramesProcessed);
+ status_t lStatus = handle->initCheck();
+ if (lStatus == OK) {
+ lStatus = effect->addHandle(handle.get());
+ }
+ if (lStatus != NO_ERROR && lStatus != ALREADY_EXISTS) {
+ if (effectCreated) {
+ chain->removeEffect(effect);
+ }
+ } else {
+ if (enabled != NULL) {
+ *enabled = (int)effect->isEnabled();
+ }
+ if (chainCreated) {
+ putOrphanEffectChain_l(chain);
+ }
+ }
+ *status = lStatus;
+ return handle;
+}
+
status_t AudioFlinger::moveEffects(audio_session_t sessionId, audio_io_handle_t srcIo,
audio_io_handle_t dstIo)
NO_THREAD_SAFETY_ANALYSIS
@@ -4487,7 +4588,7 @@
if (srcThread != nullptr) {
srcThread->removeEffect_l(effect);
} else {
- chain->removeEffect_l(effect);
+ chain->removeEffect(effect);
}
removed.add(effect);
status = dstThread->addEffect_ll(effect);
@@ -4730,7 +4831,7 @@
ALOGV("updateOrphanEffectChains session %d index %zd", session, index);
if (index >= 0) {
sp<IAfEffectChain> chain = mOrphanEffectChains.valueAt(index);
- if (chain->removeEffect_l(effect, true) == 0) {
+ if (chain->removeEffect(effect, true) == 0) {
ALOGV("updateOrphanEffectChains removing effect chain at index %zd", index);
mOrphanEffectChains.removeItemsAt(index);
}
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 7c26f72..4e46bea 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -703,6 +703,16 @@
sp<Client> registerPid(pid_t pid) EXCLUDES_AudioFlinger_ClientMutex; // always returns non-0
+ sp<IAfEffectHandle> createOrphanEffect_l(const sp<Client>& client,
+ const sp<media::IEffectClient>& effectClient,
+ int32_t priority,
+ audio_session_t sessionId,
+ effect_descriptor_t *desc,
+ int *enabled,
+ status_t *status /*non-NULL*/,
+ bool pinned,
+ bool notifyFramesProcessed) REQUIRES(mutex());
+
// for use from destructor
status_t closeOutput_nonvirtual(audio_io_handle_t output) EXCLUDES_AudioFlinger_Mutex;
status_t closeInput_nonvirtual(audio_io_handle_t input) EXCLUDES_AudioFlinger_Mutex;
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index 10a8883..012c2fe 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -2157,27 +2157,31 @@
/* static */
sp<IAfEffectChain> IAfEffectChain::create(
const sp<IAfThreadBase>& thread,
- audio_session_t sessionId)
+ audio_session_t sessionId,
+ const sp<IAfThreadCallback>& afThreadCallback)
{
- return sp<EffectChain>::make(thread, sessionId);
+ return sp<EffectChain>::make(thread, sessionId, afThreadCallback);
}
-EffectChain::EffectChain(const sp<IAfThreadBase>& thread,
- audio_session_t sessionId)
+EffectChain::EffectChain(const sp<IAfThreadBase>& thread, audio_session_t sessionId,
+ const sp<IAfThreadCallback>& afThreadCallback)
: mSessionId(sessionId), mActiveTrackCnt(0), mTrackCnt(0), mTailBufferCount(0),
mLeftVolume(UINT_MAX), mRightVolume(UINT_MAX),
mNewLeftVolume(UINT_MAX), mNewRightVolume(UINT_MAX),
- mEffectCallback(new EffectCallback(wp<EffectChain>(this), thread))
+ mEffectCallback(new EffectCallback(wp<EffectChain>(this), thread, afThreadCallback))
{
- mStrategy = thread->getStrategyForStream(AUDIO_STREAM_MUSIC);
- mMaxTailBuffers = ((kProcessTailDurationMs * thread->sampleRate()) / 1000) /
- thread->frameCount();
+ if (thread != nullptr) {
+ mStrategy = thread->getStrategyForStream(AUDIO_STREAM_MUSIC);
+ mMaxTailBuffers =
+ ((kProcessTailDurationMs * thread->sampleRate()) / 1000) /
+ thread->frameCount();
+ }
}
-// getEffectFromDesc_l() must be called with IAfThreadBase::mutex() held
-sp<IAfEffectModule> EffectChain::getEffectFromDesc_l(
+sp<IAfEffectModule> EffectChain::getEffectFromDesc(
effect_descriptor_t *descriptor) const
{
+ audio_utils::lock_guard _l(mutex());
size_t size = mEffects.size();
for (size_t i = 0; i < size; i++) {
@@ -2191,6 +2195,7 @@
// getEffectFromId_l() must be called with IAfThreadBase::mutex() held
sp<IAfEffectModule> EffectChain::getEffectFromId_l(int id) const
{
+ audio_utils::lock_guard _l(mutex());
size_t size = mEffects.size();
for (size_t i = 0; i < size; i++) {
@@ -2206,6 +2211,7 @@
sp<IAfEffectModule> EffectChain::getEffectFromType_l(
const effect_uuid_t *type) const
{
+ audio_utils::lock_guard _l(mutex());
size_t size = mEffects.size();
for (size_t i = 0; i < size; i++) {
@@ -2296,8 +2302,7 @@
}
}
-// createEffect_l() must be called with IAfThreadBase::mutex() held
-status_t EffectChain::createEffect_l(sp<IAfEffectModule>& effect,
+status_t EffectChain::createEffect(sp<IAfEffectModule>& effect,
effect_descriptor_t *desc,
int id,
audio_session_t sessionId,
@@ -2307,7 +2312,7 @@
effect = new EffectModule(mEffectCallback, desc, id, sessionId, pinned, AUDIO_PORT_HANDLE_NONE);
status_t lStatus = effect->status();
if (lStatus == NO_ERROR) {
- lStatus = addEffect_ll(effect);
+ lStatus = addEffect_l(effect);
}
if (lStatus != NO_ERROR) {
effect.clear();
@@ -2315,14 +2320,13 @@
return lStatus;
}
-// addEffect_l() must be called with IAfThreadBase::mutex() held
-status_t EffectChain::addEffect_l(const sp<IAfEffectModule>& effect)
+status_t EffectChain::addEffect(const sp<IAfEffectModule>& effect)
{
audio_utils::lock_guard _l(mutex());
- return addEffect_ll(effect);
+ return addEffect_l(effect);
}
-// addEffect_l() must be called with IAfThreadBase::mutex() and EffectChain::mutex() held
-status_t EffectChain::addEffect_ll(const sp<IAfEffectModule>& effect)
+// addEffect_l() must be called with EffectChain::mutex() held
+status_t EffectChain::addEffect_l(const sp<IAfEffectModule>& effect)
{
effect->setCallback(mEffectCallback);
@@ -2350,7 +2354,7 @@
// by insert effects
effect->setOutBuffer(mInBuffer);
} else {
- ssize_t idx_insert = getInsertIndex_ll(desc);
+ ssize_t idx_insert = getInsertIndex_l(desc);
if (idx_insert < 0) {
return INVALID_OPERATION;
}
@@ -2411,7 +2415,7 @@
return std::nullopt;
}
-ssize_t EffectChain::getInsertIndex_ll(const effect_descriptor_t& desc) {
+ssize_t EffectChain::getInsertIndex_l(const effect_descriptor_t& desc) {
// Insert effects are inserted at the end of mEffects vector as they are processed
// after track and auxiliary effects.
// Insert effect order as a function of indicated preference:
@@ -2484,8 +2488,7 @@
return idx_insert;
}
-// removeEffect_l() must be called with IAfThreadBase::mutex() held
-size_t EffectChain::removeEffect_l(const sp<IAfEffectModule>& effect,
+size_t EffectChain::removeEffect(const sp<IAfEffectModule>& effect,
bool release)
{
audio_utils::lock_guard _l(mutex());
@@ -2536,6 +2539,7 @@
// setDevices_l() must be called with IAfThreadBase::mutex() held
void EffectChain::setDevices_l(const AudioDeviceTypeAddrVector &devices)
{
+ audio_utils::lock_guard _l(mutex());
size_t size = mEffects.size();
for (size_t i = 0; i < size; i++) {
mEffects[i]->setDevices(devices);
@@ -2545,6 +2549,7 @@
// setInputDevice_l() must be called with IAfThreadBase::mutex() held
void EffectChain::setInputDevice_l(const AudioDeviceTypeAddr &device)
{
+ audio_utils::lock_guard _l(mutex());
size_t size = mEffects.size();
for (size_t i = 0; i < size; i++) {
mEffects[i]->setInputDevice(device);
@@ -2554,6 +2559,7 @@
// setMode_l() must be called with IAfThreadBase::mutex() held
void EffectChain::setMode_l(audio_mode_t mode)
{
+ audio_utils::lock_guard _l(mutex());
size_t size = mEffects.size();
for (size_t i = 0; i < size; i++) {
mEffects[i]->setMode(mode);
@@ -2563,6 +2569,7 @@
// setAudioSource_l() must be called with IAfThreadBase::mutex() held
void EffectChain::setAudioSource_l(audio_source_t source)
{
+ audio_utils::lock_guard _l(mutex());
size_t size = mEffects.size();
for (size_t i = 0; i < size; i++) {
mEffects[i]->setAudioSource(source);
@@ -2668,8 +2675,12 @@
}
}
-// containsHapticGeneratingEffect_l must be called with
-// IAfThreadBase::mutex() or EffectChain::mutex() held
+bool EffectChain::containsHapticGeneratingEffect()
+{
+ audio_utils::lock_guard _l(mutex());
+ return containsHapticGeneratingEffect_l();
+}
+// containsHapticGeneratingEffect_l must be called with EffectChain::mutex() held
bool EffectChain::containsHapticGeneratingEffect_l()
{
for (size_t i = 0; i < mEffects.size(); ++i) {
@@ -2810,7 +2821,7 @@
}
if (desc->mRefCount++ == 0) {
Vector< sp<IAfEffectModule> > effects;
- getSuspendEligibleEffects_l(effects);
+ getSuspendEligibleEffects(effects);
for (size_t i = 0; i < effects.size(); i++) {
setEffectSuspended_l(&effects[i]->desc().type, true);
}
@@ -2860,7 +2871,7 @@
return false;
}
-bool EffectChain::isEffectEligibleForSuspend_l(const effect_descriptor_t& desc)
+bool EffectChain::isEffectEligibleForSuspend(const effect_descriptor_t& desc)
{
// auxiliary effects and visualizer are never suspended on output mix
if ((mSessionId == AUDIO_SESSION_OUTPUT_MIX) &&
@@ -2873,12 +2884,13 @@
return true;
}
-void EffectChain::getSuspendEligibleEffects_l(
+void EffectChain::getSuspendEligibleEffects(
Vector< sp<IAfEffectModule> > &effects)
{
effects.clear();
+ audio_utils::lock_guard _l(mutex());
for (size_t i = 0; i < mEffects.size(); i++) {
- if (isEffectEligibleForSuspend_l(mEffects[i]->desc())) {
+ if (isEffectEligibleForSuspend(mEffects[i]->desc())) {
effects.add(mEffects[i]);
}
}
@@ -2899,7 +2911,7 @@
if (index < 0) {
return;
}
- if (!isEffectEligibleForSuspend_l(effect->desc())) {
+ if (!isEffectEligibleForSuspend(effect->desc())) {
return;
}
setEffectSuspended_l(&effect->desc().type, enabled);
@@ -2947,6 +2959,12 @@
void EffectChain::setThread(const sp<IAfThreadBase>& thread)
{
+ if (thread != nullptr) {
+ mStrategy = thread->getStrategyForStream(AUDIO_STREAM_MUSIC);
+ mMaxTailBuffers =
+ ((kProcessTailDurationMs * thread->sampleRate()) / 1000) /
+ thread->frameCount();
+ }
audio_utils::lock_guard _l(mutex());
mEffectCallback->setThread(thread);
}
@@ -3136,7 +3154,7 @@
uint32_t EffectChain::EffectCallback::sampleRate() const {
const sp<IAfThreadBase> t = thread().promote();
if (t == nullptr) {
- return 0;
+ return DEFAULT_OUTPUT_SAMPLE_RATE;
}
return t->sampleRate();
}
@@ -3144,6 +3162,7 @@
audio_channel_mask_t EffectChain::EffectCallback::inChannelMask(int id) const
NO_THREAD_SAFETY_ANALYSIS
// calling function 'hasAudioSession_l' requires holding mutex 'ThreadBase_Mutex' exclusively
+// calling function 'isFirstEffect_l' requires holding mutex 'EffectChain_Mutex' exclusively
{
const sp<IAfThreadBase> t = thread().promote();
if (t == nullptr) {
@@ -3156,7 +3175,7 @@
if (mThreadType == IAfThreadBase::SPATIALIZER) {
if (c->sessionId() == AUDIO_SESSION_OUTPUT_STAGE) {
- if (c->isFirstEffect(id)) {
+ if (c->isFirstEffect_l(id)) {
return t->mixerChannelMask();
} else {
return t->channelMask();
@@ -3224,7 +3243,8 @@
size_t EffectChain::EffectCallback::frameCount() const {
const sp<IAfThreadBase> t = thread().promote();
if (t == nullptr) {
- return 0;
+ // frameCount cannot be zero.
+ return 1;
}
return t->frameCount();
}
diff --git a/services/audioflinger/Effects.h b/services/audioflinger/Effects.h
index 5e527d3..505f3b3 100644
--- a/services/audioflinger/Effects.h
+++ b/services/audioflinger/Effects.h
@@ -234,9 +234,9 @@
bool isSpatializer() const final;
status_t setHapticScale_l(int id, os::HapticScale hapticScale) final
- REQUIRES(audio_utils::ThreadBase_Mutex) EXCLUDES_EffectBase_Mutex;
+ REQUIRES(audio_utils::EffectChain_Mutex) EXCLUDES_EffectBase_Mutex;
status_t setVibratorInfo_l(const media::AudioVibratorInfo& vibratorInfo) final
- REQUIRES(audio_utils::ThreadBase_Mutex) EXCLUDES_EffectBase_Mutex;
+ REQUIRES(audio_utils::EffectChain_Mutex) EXCLUDES_EffectBase_Mutex;
status_t sendMetadata_ll(const std::vector<playback_track_metadata_v7_t>& metadata) final
REQUIRES(audio_utils::ThreadBase_Mutex,
audio_utils::EffectChain_Mutex) EXCLUDES_EffectBase_Mutex;
@@ -412,7 +412,9 @@
// it also provide it's own input buffer used by the track as accumulation buffer.
class EffectChain : public IAfEffectChain {
public:
- EffectChain(const sp<IAfThreadBase>& thread, audio_session_t sessionId);
+ EffectChain(const sp<IAfThreadBase>& thread,
+ audio_session_t sessionId,
+ const sp<IAfThreadCallback>& afThreadCallback);
void process_l() final REQUIRES(audio_utils::EffectChain_Mutex);
@@ -420,25 +422,25 @@
return mMutex;
}
- status_t createEffect_l(sp<IAfEffectModule>& effect, effect_descriptor_t* desc, int id,
+ status_t createEffect(sp<IAfEffectModule>& effect, effect_descriptor_t* desc, int id,
audio_session_t sessionId, bool pinned) final
- REQUIRES(audio_utils::ThreadBase_Mutex) EXCLUDES_EffectChain_Mutex;
+ EXCLUDES_EffectChain_Mutex;
+ status_t addEffect(const sp<IAfEffectModule>& handle) final
+ EXCLUDES_EffectChain_Mutex;
status_t addEffect_l(const sp<IAfEffectModule>& handle) final
- REQUIRES(audio_utils::ThreadBase_Mutex) EXCLUDES_EffectChain_Mutex;
- status_t addEffect_ll(const sp<IAfEffectModule>& handle) final
- REQUIRES(audio_utils::ThreadBase_Mutex, audio_utils::EffectChain_Mutex);
- size_t removeEffect_l(const sp<IAfEffectModule>& handle, bool release = false) final
- REQUIRES(audio_utils::ThreadBase_Mutex) EXCLUDES_EffectChain_Mutex;
+ REQUIRES(audio_utils::EffectChain_Mutex);
+ size_t removeEffect(const sp<IAfEffectModule>& handle, bool release = false) final
+ EXCLUDES_EffectChain_Mutex;
audio_session_t sessionId() const final { return mSessionId; }
void setSessionId(audio_session_t sessionId) final { mSessionId = sessionId; }
- sp<IAfEffectModule> getEffectFromDesc_l(effect_descriptor_t* descriptor) const final
- REQUIRES(audio_utils::ThreadBase_Mutex);
+ sp<IAfEffectModule> getEffectFromDesc(effect_descriptor_t* descriptor) const final
+ EXCLUDES_EffectChain_Mutex;
sp<IAfEffectModule> getEffectFromId_l(int id) const final
- REQUIRES(audio_utils::ThreadBase_Mutex);
+ REQUIRES(audio_utils::ThreadBase_Mutex) EXCLUDES_EffectChain_Mutex;
sp<IAfEffectModule> getEffectFromType_l(const effect_uuid_t* type) const final
- REQUIRES(audio_utils::ThreadBase_Mutex);
+ REQUIRES(audio_utils::ThreadBase_Mutex) EXCLUDES_EffectChain_Mutex;
std::vector<int> getEffectIds_l() const final REQUIRES(audio_utils::ThreadBase_Mutex);
// FIXME use float to improve the dynamic range
@@ -446,11 +448,13 @@
bool force = false) final EXCLUDES_EffectChain_Mutex;
void resetVolume_l() final REQUIRES(audio_utils::EffectChain_Mutex);
void setDevices_l(const AudioDeviceTypeAddrVector& devices) final
- REQUIRES(audio_utils::ThreadBase_Mutex);
+ REQUIRES(audio_utils::ThreadBase_Mutex) EXCLUDES_EffectChain_Mutex;
void setInputDevice_l(const AudioDeviceTypeAddr& device) final
- REQUIRES(audio_utils::ThreadBase_Mutex);
- void setMode_l(audio_mode_t mode) final REQUIRES(audio_utils::ThreadBase_Mutex);
- void setAudioSource_l(audio_source_t source) final REQUIRES(audio_utils::ThreadBase_Mutex);
+ REQUIRES(audio_utils::ThreadBase_Mutex) EXCLUDES_EffectChain_Mutex;
+ void setMode_l(audio_mode_t mode) final
+ REQUIRES(audio_utils::ThreadBase_Mutex) EXCLUDES_EffectChain_Mutex;
+ void setAudioSource_l(audio_source_t source) final
+ REQUIRES(audio_utils::ThreadBase_Mutex) EXCLUDES_EffectChain_Mutex;
void setInBuffer(const sp<EffectBufferHalInterface>& buffer) final {
mInBuffer = buffer;
@@ -517,8 +521,11 @@
bool isCompatibleWithThread_l(const sp<IAfThreadBase>& thread) const final
REQUIRES(audio_utils::ThreadBase_Mutex) EXCLUDES_EffectChain_Mutex;
- // Requires either IAfThreadBase::mutex() or EffectChain::mutex() held
- bool containsHapticGeneratingEffect_l() final;
+ bool containsHapticGeneratingEffect() final
+ EXCLUDES_EffectChain_Mutex;
+
+ bool containsHapticGeneratingEffect_l() final
+ REQUIRES(audio_utils::EffectChain_Mutex);
void setHapticScale_l(int id, os::HapticScale hapticScale) final
REQUIRES(audio_utils::ThreadBase_Mutex) EXCLUDES_EffectChain_Mutex;
@@ -527,15 +534,19 @@
wp<IAfThreadBase> thread() const final { return mEffectCallback->thread(); }
- bool isFirstEffect(int id) const final {
+ bool isFirstEffect_l(int id) const final REQUIRES(audio_utils::EffectChain_Mutex) {
return !mEffects.isEmpty() && id == mEffects[0]->id();
}
void dump(int fd, const Vector<String16>& args) const final;
- size_t numberOfEffects() const final { return mEffects.size(); }
+ size_t numberOfEffects() const final {
+ audio_utils::lock_guard _l(mutex());
+ return mEffects.size();
+ }
sp<IAfEffectModule> getEffectModule(size_t index) const final {
+ audio_utils::lock_guard _l(mutex());
return mEffects[index];
}
@@ -560,11 +571,13 @@
// Note: ctors taking a weak pointer to their owner must not promote it
// during construction (but may keep a reference for later promotion).
EffectCallback(const wp<EffectChain>& owner,
- const sp<IAfThreadBase>& thread) // we take a sp<> but store a wp<>.
+ const sp<IAfThreadBase>& thread,
+ const sp<IAfThreadCallback>& afThreadCallback) // we take a sp<> but store a wp<>.
: mChain(owner)
- , mThread(thread) {
- mThreadType = thread->type();
- mAfThreadCallback = thread->afThreadCallback();
+ , mThread(thread), mAfThreadCallback(afThreadCallback) {
+ if (thread != nullptr) {
+ mThreadType = thread->type();
+ }
}
status_t createEffectHal(const effect_uuid_t *pEffectUuid,
@@ -606,6 +619,9 @@
wp<IAfEffectChain> chain() const final { return mChain; }
bool isAudioPolicyReady() const final {
+ if (mAfThreadCallback == nullptr) {
+ return false;
+ }
return mAfThreadCallback->isAudioPolicyReady();
}
@@ -613,8 +629,10 @@
void setThread(const sp<IAfThreadBase>& thread) {
mThread = thread;
- mThreadType = thread->type();
- mAfThreadCallback = thread->afThreadCallback();
+ if (thread != nullptr) {
+ mThreadType = thread->type();
+ mAfThreadCallback = thread->afThreadCallback();
+ }
}
bool hasThreadAttached() const {
return thread().promote() != nullptr;
@@ -623,7 +641,7 @@
const wp<IAfEffectChain> mChain;
mediautils::atomic_wp<IAfThreadBase> mThread;
sp<IAfThreadCallback> mAfThreadCallback;
- IAfThreadBase::type_t mThreadType;
+ IAfThreadBase::type_t mThreadType = IAfThreadBase::MIXER;
};
DISALLOW_COPY_AND_ASSIGN(EffectChain);
@@ -639,8 +657,8 @@
// get a list of effect modules to suspend when an effect of the type
// passed is enabled.
- void getSuspendEligibleEffects_l(Vector<sp<IAfEffectModule>>& effects)
- REQUIRES(audio_utils::ThreadBase_Mutex);
+ void getSuspendEligibleEffects(Vector<sp<IAfEffectModule>>& effects)
+ EXCLUDES_EffectChain_Mutex;
// get an effect module if it is currently enable
sp<IAfEffectModule> getEffectIfEnabled_l(const effect_uuid_t* type)
@@ -648,8 +666,7 @@
// true if the effect whose descriptor is passed can be suspended
// OEMs can modify the rules implemented in this method to exclude specific effect
// types or implementations from the suspend/restore mechanism.
- bool isEffectEligibleForSuspend_l(const effect_descriptor_t& desc)
- REQUIRES(audio_utils::ThreadBase_Mutex);
+ bool isEffectEligibleForSuspend(const effect_descriptor_t& desc);
static bool isEffectEligibleForBtNrecSuspend_l(const effect_uuid_t* type)
REQUIRES(audio_utils::ThreadBase_Mutex);
@@ -662,15 +679,15 @@
void setVolumeForOutput_l(uint32_t left, uint32_t right)
REQUIRES(audio_utils::EffectChain_Mutex);
- ssize_t getInsertIndex_ll(const effect_descriptor_t& desc)
- REQUIRES(audio_utils::ThreadBase_Mutex, audio_utils::EffectChain_Mutex);
+ ssize_t getInsertIndex_l(const effect_descriptor_t& desc)
+ REQUIRES(audio_utils::EffectChain_Mutex);
std::optional<size_t> findVolumeControl_l(size_t from, size_t to) const
REQUIRES(audio_utils::EffectChain_Mutex);
// mutex protecting effect list
mutable audio_utils::mutex mMutex{audio_utils::MutexOrder::kEffectChain_Mutex};
- Vector<sp<IAfEffectModule>> mEffects; // list of effect modules
+ Vector<sp<IAfEffectModule>> mEffects GUARDED_BY(mutex()); // list of effect modules
audio_session_t mSessionId; // audio session ID
sp<EffectBufferHalInterface> mInBuffer; // chain input buffer
sp<EffectBufferHalInterface> mOutBuffer; // chain output buffer
diff --git a/services/audioflinger/IAfEffect.h b/services/audioflinger/IAfEffect.h
index fd4dd62..0c8e9e3 100644
--- a/services/audioflinger/IAfEffect.h
+++ b/services/audioflinger/IAfEffect.h
@@ -181,9 +181,9 @@
virtual bool isSpatializer() const = 0;
virtual status_t setHapticScale_l(int id, os::HapticScale hapticScale)
- REQUIRES(audio_utils::ThreadBase_Mutex) EXCLUDES_EffectBase_Mutex = 0;
+ REQUIRES(audio_utils::EffectChain_Mutex) EXCLUDES_EffectBase_Mutex = 0;
virtual status_t setVibratorInfo_l(const media::AudioVibratorInfo& vibratorInfo)
- REQUIRES(audio_utils::ThreadBase_Mutex) EXCLUDES_EffectBase_Mutex = 0;
+ REQUIRES(audio_utils::EffectChain_Mutex) EXCLUDES_EffectBase_Mutex = 0;
virtual status_t sendMetadata_ll(const std::vector<playback_track_metadata_v7_t>& metadata)
REQUIRES(audio_utils::ThreadBase_Mutex,
audio_utils::EffectChain_Mutex) EXCLUDES_EffectBase_Mutex = 0;
@@ -218,7 +218,8 @@
public:
static sp<IAfEffectChain> create(
const sp<IAfThreadBase>& thread,
- audio_session_t sessionId);
+ audio_session_t sessionId,
+ const sp<IAfThreadCallback>& afThreadCallback);
// special key used for an entry in mSuspendedEffects keyed vector
// corresponding to a suspend all request.
@@ -232,35 +233,36 @@
virtual audio_utils::mutex& mutex() const RETURN_CAPABILITY(audio_utils::EffectChain_Mutex) = 0;
- virtual status_t createEffect_l(sp<IAfEffectModule>& effect, effect_descriptor_t* desc, int id,
+ virtual status_t createEffect(sp<IAfEffectModule>& effect, effect_descriptor_t* desc, int id,
audio_session_t sessionId, bool pinned)
- REQUIRES(audio_utils::ThreadBase_Mutex) EXCLUDES_EffectChain_Mutex = 0;
+ EXCLUDES_EffectChain_Mutex = 0;
+ virtual status_t addEffect(const sp<IAfEffectModule>& handle)
+ EXCLUDES_EffectChain_Mutex = 0;
virtual status_t addEffect_l(const sp<IAfEffectModule>& handle)
- REQUIRES(audio_utils::ThreadBase_Mutex) EXCLUDES_EffectChain_Mutex = 0;
- virtual status_t addEffect_ll(const sp<IAfEffectModule>& handle)
- REQUIRES(audio_utils::ThreadBase_Mutex, audio_utils::EffectChain_Mutex) = 0;
- virtual size_t removeEffect_l(const sp<IAfEffectModule>& handle,
+ REQUIRES(audio_utils::EffectChain_Mutex) = 0;
+ virtual size_t removeEffect(const sp<IAfEffectModule>& handle,
bool release = false) EXCLUDES_EffectChain_Mutex = 0;
virtual audio_session_t sessionId() const = 0;
virtual void setSessionId(audio_session_t sessionId) = 0;
- virtual sp<IAfEffectModule> getEffectFromDesc_l(effect_descriptor_t* descriptor) const
- REQUIRES(audio_utils::ThreadBase_Mutex) = 0;
+ virtual sp<IAfEffectModule> getEffectFromDesc(effect_descriptor_t* descriptor) const
+ EXCLUDES_EffectChain_Mutex = 0;
virtual sp<IAfEffectModule> getEffectFromId_l(int id) const
- REQUIRES(audio_utils::ThreadBase_Mutex) = 0;
+ REQUIRES(audio_utils::ThreadBase_Mutex) EXCLUDES_EffectChain_Mutex = 0;
virtual sp<IAfEffectModule> getEffectFromType_l(const effect_uuid_t* type) const
- REQUIRES(audio_utils::ThreadBase_Mutex) = 0;
+ REQUIRES(audio_utils::ThreadBase_Mutex) EXCLUDES_EffectChain_Mutex = 0;
virtual std::vector<int> getEffectIds_l() const = 0;
virtual bool setVolume(uint32_t* left, uint32_t* right,
bool force = false) EXCLUDES_EffectChain_Mutex = 0;
virtual void resetVolume_l() REQUIRES(audio_utils::EffectChain_Mutex) = 0;
virtual void setDevices_l(const AudioDeviceTypeAddrVector& devices)
- REQUIRES(audio_utils::ThreadBase_Mutex) = 0;
+ REQUIRES(audio_utils::ThreadBase_Mutex) EXCLUDES_EffectChain_Mutex = 0;
virtual void setInputDevice_l(const AudioDeviceTypeAddr& device)
- REQUIRES(audio_utils::ThreadBase_Mutex) = 0;
- virtual void setMode_l(audio_mode_t mode) REQUIRES(audio_utils::ThreadBase_Mutex) = 0;
+ REQUIRES(audio_utils::ThreadBase_Mutex) EXCLUDES_EffectChain_Mutex = 0;
+ virtual void setMode_l(audio_mode_t mode)
+ REQUIRES(audio_utils::ThreadBase_Mutex) EXCLUDES_EffectChain_Mutex = 0;
virtual void setAudioSource_l(audio_source_t source)
REQUIRES(audio_utils::ThreadBase_Mutex) = 0;
@@ -317,7 +319,11 @@
virtual bool isCompatibleWithThread_l(const sp<IAfThreadBase>& thread) const
REQUIRES(audio_utils::ThreadBase_Mutex) EXCLUDES_EffectChain_Mutex = 0;
- virtual bool containsHapticGeneratingEffect_l() = 0;
+ virtual bool containsHapticGeneratingEffect()
+ EXCLUDES_EffectChain_Mutex = 0;
+
+ virtual bool containsHapticGeneratingEffect_l()
+ REQUIRES(audio_utils::EffectChain_Mutex) = 0;
virtual void setHapticScale_l(int id, os::HapticScale hapticScale)
REQUIRES(audio_utils::ThreadBase_Mutex) EXCLUDES_EffectChain_Mutex = 0;
@@ -327,7 +333,7 @@
virtual wp<IAfThreadBase> thread() const = 0;
virtual void setThread(const sp<IAfThreadBase>& thread) EXCLUDES_EffectChain_Mutex = 0;
- virtual bool isFirstEffect(int id) const = 0;
+ virtual bool isFirstEffect_l(int id) const REQUIRES(audio_utils::EffectChain_Mutex) = 0;
virtual size_t numberOfEffects() const = 0;
virtual sp<IAfEffectModule> getEffectModule(size_t index) const = 0;
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index b519289..f9a093a 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();
@@ -4800,7 +4801,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.