Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b01c96c0 authored by Andy Hung's avatar Andy Hung
Browse files

Effects: Update to audio_utils mutex

Test: atest AudioTrackTest AudioRecordTest
Test: atest AAudioTests AudioTrackOffloadTest
Test: atest AudioPlaybackCaptureTest
Test: Camera YouTube
Bug: 298534151
Merged-In: I2ff0b2748110b56da238db7dd74b3c6692ffce39
Change-Id: I2ff0b2748110b56da238db7dd74b3c6692ffce39
parent 1082fce9
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -4389,7 +4389,7 @@ status_t AudioFlinger::moveEffectChain_l(audio_session_t sessionId,
        // If we do not take the dstChain lock, it is possible that processing is ongoing
        // while we are starting the effect.  This can cause glitches with volume,
        // see b/202360137.
        dstChain->lock();
        dstChain->mutex().lock();
        for (const auto& effect : removed) {
            if (effect->state() == IAfEffectModule::ACTIVE ||
                    effect->state() == IAfEffectModule::STOPPING) {
@@ -4397,7 +4397,7 @@ status_t AudioFlinger::moveEffectChain_l(audio_session_t sessionId,
                effect->start();
            }
        }
        dstChain->unlock();
        dstChain->mutex().unlock();
    }

    if (status != NO_ERROR) {
+7 −7
Original line number Diff line number Diff line
@@ -59,7 +59,7 @@ void DeviceEffectManager::onCreateAudioPatch(audio_patch_handle_t handle,
    ALOGV("%s handle %d mHalHandle %d device sink %08x",
            __func__, handle, patch.mHalHandle,
            patch.mAudioPatch.num_sinks > 0 ? patch.mAudioPatch.sinks[0].ext.device.type : 0);
    Mutex::Autolock _l(mLock);
    audio_utils::lock_guard _l(mutex());
    for (auto& effect : mDeviceEffects) {
        status_t status = effect.second->onCreatePatch(handle, patch);
        ALOGV("%s Effect onCreatePatch status %d", __func__, status);
@@ -69,13 +69,13 @@ void DeviceEffectManager::onCreateAudioPatch(audio_patch_handle_t handle,

void DeviceEffectManager::onReleaseAudioPatch(audio_patch_handle_t handle) {
    ALOGV("%s", __func__);
    Mutex::Autolock _l(mLock);
    audio_utils::lock_guard _l(mutex());
    for (auto& effect : mDeviceEffects) {
        effect.second->onReleasePatch(handle);
    }
}

// DeviceEffectManager::createEffect_l() must be called with AudioFlinger::mLock held
// DeviceEffectManager::createEffect_l() must be called with AudioFlinger::mutex() held
sp<IAfEffectHandle> DeviceEffectManager::createEffect_l(
        effect_descriptor_t *descriptor,
        const AudioDeviceTypeAddr& device,
@@ -97,7 +97,7 @@ sp<IAfEffectHandle> DeviceEffectManager::createEffect_l(
    }

    {
        Mutex::Autolock _l(mLock);
        audio_utils::lock_guard _l(mutex());
        auto iter = mDeviceEffects.find(device);
        if (iter != mDeviceEffects.end()) {
            effect = iter->second;
@@ -173,7 +173,7 @@ status_t DeviceEffectManager::createEffectHal(
void DeviceEffectManager::dump(int fd)
NO_THREAD_SAFETY_ANALYSIS  // conditional try lock
{
    const bool locked = afutils::dumpTryLock(mLock);
    const bool locked = afutils::dumpTryLock(mutex());
    if (!locked) {
        String8 result("DeviceEffectManager may be deadlocked\n");
        write(fd, result.c_str(), result.size());
@@ -190,13 +190,13 @@ NO_THREAD_SAFETY_ANALYSIS // conditional try lock
    }

    if (locked) {
        mLock.unlock();
        mutex().unlock();
    }
}

size_t DeviceEffectManager::removeEffect(const sp<IAfDeviceEffectProxy>& effect)
{
    Mutex::Autolock _l(mLock);
    audio_utils::lock_guard _l(mutex());
    mDeviceEffects.erase(effect->device());
    return mDeviceEffects.size();
}
+2 −3
Original line number Diff line number Diff line
@@ -20,8 +20,6 @@
#include "IAfEffect.h"
#include "PatchCommandThread.h"

#include <utils/Mutex.h>  // avoid transitive dependency

namespace android {

class IAfDeviceEffectManagerCallback : public virtual RefBase {
@@ -77,7 +75,8 @@ public:
private:
    status_t checkEffectCompatibility(const effect_descriptor_t *desc);

    Mutex mLock;
    audio_utils::mutex& mutex() const { return mMutex; }
    mutable audio_utils::mutex mMutex;
    const sp<IAfDeviceEffectManagerCallback> mAfDeviceEffectManagerCallback;
    const sp<DeviceEffectManagerCallback> mMyCallback;
    std::map<AudioDeviceTypeAddr, sp<IAfDeviceEffectProxy>> mDeviceEffects;
+69 −69
Original line number Diff line number Diff line
@@ -109,7 +109,7 @@ EffectBase::EffectBase(const sp<EffectCallbackInterface>& callback,
{
}

// must be called with EffectModule::mLock held
// must be called with EffectModule::mutex() held
status_t EffectBase::setEnabled_l(bool enabled)
{

@@ -155,7 +155,7 @@ status_t EffectBase::setEnabled(bool enabled, bool fromHandle)
{
    status_t status;
    {
        Mutex::Autolock _l(mLock);
        audio_utils::lock_guard _l(mutex());
        status = setEnabled_l(enabled);
    }
    if (fromHandle) {
@@ -190,13 +190,13 @@ bool EffectBase::isEnabled() const

void EffectBase::setSuspended(bool suspended)
{
    Mutex::Autolock _l(mLock);
    audio_utils::lock_guard _l(mutex());
    mSuspended = suspended;
}

bool EffectBase::suspended() const
{
    Mutex::Autolock _l(mLock);
    audio_utils::lock_guard _l(mutex());
    return mSuspended;
}

@@ -204,7 +204,7 @@ status_t EffectBase::addHandle(IAfEffectHandle *handle)
{
    status_t status;

    Mutex::Autolock _l(mLock);
    audio_utils::lock_guard _l(mutex());
    int priority = handle->priority();
    size_t size = mHandles.size();
    IAfEffectHandle *controlHandle = nullptr;
@@ -250,7 +250,7 @@ status_t EffectBase::updatePolicyState()
    product_strategy_t strategy = PRODUCT_STRATEGY_NONE;

    {
        Mutex::Autolock _l(mLock);
        audio_utils::lock_guard _l(mutex());

        if ((isInternal_l() && !mPolicyRegistered)
                || !getCallback()->isAudioPolicyReady()) {
@@ -284,7 +284,7 @@ status_t EffectBase::updatePolicyState()
            return NO_ERROR;
        }
    }
    mPolicyLock.lock();
    policyMutex().lock();
    ALOGV("%s name %s id %d session %d doRegister %d registered %d doEnable %d enabled %d",
        __func__, mDescriptor.name, mId, mSessionId, doRegister, registered, doEnable, enabled);
    if (doRegister) {
@@ -302,7 +302,7 @@ status_t EffectBase::updatePolicyState()
    if (registered && doEnable) {
        status = AudioSystem::setEffectEnabled(mId, enabled);
    }
    mPolicyLock.unlock();
    policyMutex().unlock();

    return status;
}
@@ -310,7 +310,7 @@ status_t EffectBase::updatePolicyState()

ssize_t EffectBase::removeHandle(IAfEffectHandle *handle)
{
    Mutex::Autolock _l(mLock);
    audio_utils::lock_guard _l(mutex());
    return removeHandle_l(handle);
}

@@ -348,7 +348,7 @@ ssize_t EffectBase::removeHandle_l(IAfEffectHandle *handle)
    return mHandles.size();
}

// must be called with EffectModule::mLock held
// must be called with EffectModule::mutex() held
IAfEffectHandle *EffectBase::controlHandle_l()
{
    // the first valid handle in the list has control over the module
@@ -371,12 +371,12 @@ ssize_t EffectBase::disconnectHandle(IAfEffectHandle *handle, bool unpinIfLast)
        return mHandles.size();
    }

    Mutex::Autolock _l(mLock);
    audio_utils::lock_guard _l(mutex());
    ssize_t numHandles = removeHandle_l(handle);
    if ((numHandles == 0) && (!mPinned || unpinIfLast)) {
        mLock.unlock();
        mutex().unlock();
        callback->updateOrphanEffectChains(this);
        mLock.lock();
        mutex().lock();
    }
    return numHandles;
}
@@ -384,7 +384,7 @@ ssize_t EffectBase::disconnectHandle(IAfEffectHandle *handle, bool unpinIfLast)
bool EffectBase::purgeHandles()
{
    bool enabled = false;
    Mutex::Autolock _l(mLock);
    audio_utils::lock_guard _l(mutex());
    IAfEffectHandle *handle = controlHandle_l();
    if (handle != NULL) {
        enabled = handle->enabled();
@@ -509,7 +509,7 @@ NO_THREAD_SAFETY_ANALYSIS // conditional try lock

    result.appendFormat("\tEffect ID %d:\n", mId);

    const bool locked = afutils::dumpTryLock(mLock);
    const bool locked = afutils::dumpTryLock(mutex());
    // failed to lock - AudioFlinger is probably deadlocked
    if (!locked) {
        result.append("\t\tCould not lock Fx mutex:\n");
@@ -547,7 +547,7 @@ NO_THREAD_SAFETY_ANALYSIS // conditional try lock
        }
    }
    if (locked) {
        mLock.unlock();
        mutex().unlock();
    }

    write(fd, result.c_str(), result.length());
@@ -616,7 +616,7 @@ EffectModule::~EffectModule()
}

bool EffectModule::updateState() {
    Mutex::Autolock _l(mLock);
    audio_utils::lock_guard _l(mutex());

    bool started = false;
    switch (mState) {
@@ -672,7 +672,7 @@ bool EffectModule::updateState() {

void EffectModule::process()
{
    Mutex::Autolock _l(mLock);
    audio_utils::lock_guard _l(mutex());

    if (mState == DESTROYED || mEffectInterface == 0 || mInBuffer == 0 || mOutBuffer == 0) {
        return;
@@ -1013,7 +1013,7 @@ exit:

status_t EffectModule::init()
{
    Mutex::Autolock _l(mLock);
    audio_utils::lock_guard _l(mutex());
    if (mEffectInterface == 0) {
        return NO_INIT;
    }
@@ -1043,12 +1043,12 @@ void EffectModule::addEffectToHal_l()
    }
}

// start() must be called with PlaybackThread::mLock or EffectChain::mLock held
// start() must be called with PlaybackThread::mutex() or EffectChain::mutex() held
status_t EffectModule::start()
{
    status_t status;
    {
        Mutex::Autolock _l(mLock);
        audio_utils::lock_guard _l(mutex());
        status = start_l();
    }
    if (status == NO_ERROR) {
@@ -1083,7 +1083,7 @@ status_t EffectModule::start_l()

status_t EffectModule::stop()
{
    Mutex::Autolock _l(mLock);
    audio_utils::lock_guard _l(mutex());
    return stop_l();
}

@@ -1120,7 +1120,7 @@ status_t EffectModule::stop_l()
    return status;
}

// must be called with EffectChain::mLock held
// must be called with EffectChain::mutex() held
void EffectModule::release_l()
{
    if (mEffectInterface != 0) {
@@ -1156,7 +1156,7 @@ status_t EffectModule::command(int32_t cmdCode,
                     int32_t maxReplySize,
                     std::vector<uint8_t>* reply)
{
    Mutex::Autolock _l(mLock);
    audio_utils::lock_guard _l(mutex());
    ALOGVV("command(), cmdCode: %d, mEffectInterface: %p", cmdCode, mEffectInterface.get());

    if (mState == DESTROYED || mEffectInterface == 0) {
@@ -1353,7 +1353,7 @@ void EffectModule::setOutBuffer(const sp<EffectBufferHalInterface>& buffer) {

status_t EffectModule::setVolume(uint32_t *left, uint32_t *right, bool controller)
{
    AutoLockReentrant _l(mLock, mSetVolumeReentrantTid);
    AutoLockReentrant _l(mutex(), mSetVolumeReentrantTid);
    if (mStatus != NO_ERROR) {
        return mStatus;
    }
@@ -1407,7 +1407,7 @@ status_t EffectModule::sendSetAudioDevicesCommand(
        return NO_ERROR;
    }

    Mutex::Autolock _l(mLock);
    audio_utils::lock_guard _l(mutex());
    if (mStatus != NO_ERROR) {
        return mStatus;
    }
@@ -1437,7 +1437,7 @@ status_t EffectModule::setInputDevice(const AudioDeviceTypeAddr &device)

status_t EffectModule::setMode(audio_mode_t mode)
{
    Mutex::Autolock _l(mLock);
    audio_utils::lock_guard _l(mutex());
    if (mStatus != NO_ERROR) {
        return mStatus;
    }
@@ -1459,7 +1459,7 @@ status_t EffectModule::setMode(audio_mode_t mode)

status_t EffectModule::setAudioSource(audio_source_t source)
{
    Mutex::Autolock _l(mLock);
    audio_utils::lock_guard _l(mutex());
    if (mStatus != NO_ERROR) {
        return mStatus;
    }
@@ -1477,7 +1477,7 @@ status_t EffectModule::setAudioSource(audio_source_t source)

status_t EffectModule::setOffloaded(bool offloaded, audio_io_handle_t io)
{
    Mutex::Autolock _l(mLock);
    audio_utils::lock_guard _l(mutex());
    if (mStatus != NO_ERROR) {
        return mStatus;
    }
@@ -1510,7 +1510,7 @@ status_t EffectModule::setOffloaded(bool offloaded, audio_io_handle_t io)

bool EffectModule::isOffloaded() const
{
    Mutex::Autolock _l(mLock);
    audio_utils::lock_guard _l(mutex());
    return mOffloaded;
}

@@ -1581,7 +1581,7 @@ status_t EffectModule::setVibratorInfo(const media::AudioVibratorInfo& vibratorI

status_t EffectModule::getConfigs(
        audio_config_base_t* inputCfg, audio_config_base_t* outputCfg, bool* isOutput) const {
    Mutex::Autolock _l(mLock);
    audio_utils::lock_guard _l(mutex());
    if (mConfig.inputCfg.mask == 0 || mConfig.outputCfg.mask == 0) {
        return NO_INIT;
    }
@@ -1616,7 +1616,7 @@ NO_THREAD_SAFETY_ANALYSIS // conditional try lock
    EffectBase::dump(fd, args);

    String8 result;
    const bool locked = afutils::dumpTryLock(mLock);
    const bool locked = afutils::dumpTryLock(mutex());

    result.append("\t\tStatus Engine:\n");
    result.appendFormat("\t\t%03d    %p\n",
@@ -1659,7 +1659,7 @@ NO_THREAD_SAFETY_ANALYSIS // conditional try lock
    }

    if (locked) {
        mLock.unlock();
        mutex().unlock();
    }
}

@@ -1782,7 +1782,7 @@ status_t EffectHandle::initCheck() const

Status EffectHandle::enable(int32_t* _aidl_return)
{
    AutoMutex _l(mLock);
    audio_utils::lock_guard _l(mutex());
    ALOGV("enable %p", this);
    sp<IAfEffectBase> effect = mEffect.promote();
    if (effect == 0 || mDisconnected) {
@@ -1821,7 +1821,7 @@ Status EffectHandle::enable(int32_t* _aidl_return)
Status EffectHandle::disable(int32_t* _aidl_return)
{
    ALOGV("disable %p", this);
    AutoMutex _l(mLock);
    audio_utils::lock_guard _l(mutex());
    sp<IAfEffectBase> effect = mEffect.promote();
    if (effect == 0 || mDisconnected) {
        RETURN(DEAD_OBJECT);
@@ -1854,7 +1854,7 @@ Status EffectHandle::disconnect()

void EffectHandle::disconnect(bool unpinIfLast)
{
    AutoMutex _l(mLock);
    audio_utils::lock_guard _l(mutex());
    ALOGV("disconnect(%s) %p", unpinIfLast ? "true" : "false", this);
    if (mDisconnected) {
        if (unpinIfLast) {
@@ -1893,7 +1893,7 @@ Status EffectHandle::getCblk(media::SharedFileRegion* _aidl_return) {

Status EffectHandle::getConfig(
        media::EffectConfig* _config, int32_t* _aidl_return) {
    AutoMutex _l(mLock);
    audio_utils::lock_guard _l(mutex());
    sp<IAfEffectBase> effect = mEffect.promote();
    if (effect == nullptr || mDisconnected) {
        RETURN(DEAD_OBJECT);
@@ -1960,7 +1960,7 @@ Status EffectHandle::command(int32_t cmdCode,
        return disable(_aidl_return);
    }

    AutoMutex _l(mLock);
    audio_utils::lock_guard _l(mutex());
    sp<IAfEffectBase> effect = mEffect.promote();
    if (effect == 0 || mDisconnected) {
        RETURN(DEAD_OBJECT);
@@ -2174,7 +2174,7 @@ sp<IAfEffectModule> EffectChain::getEffectFromType_l(
std::vector<int> EffectChain::getEffectIds() const
{
    std::vector<int> ids;
    Mutex::Autolock _l(mLock);
    audio_utils::lock_guard _l(mutex());
    for (size_t i = 0; i < mEffects.size(); i++) {
        ids.push_back(mEffects[i]->id());
    }
@@ -2183,11 +2183,11 @@ std::vector<int> EffectChain::getEffectIds() const

void EffectChain::clearInputBuffer()
{
    Mutex::Autolock _l(mLock);
    audio_utils::lock_guard _l(mutex());
    clearInputBuffer_l();
}

// Must be called with EffectChain::mLock locked
// Must be called with EffectChain::mutex() locked
void EffectChain::clearInputBuffer_l()
{
    if (mInBuffer == NULL) {
@@ -2200,7 +2200,7 @@ void EffectChain::clearInputBuffer_l()
    mInBuffer->commit();
}

// Must be called with EffectChain::mLock locked
// Must be called with EffectChain::mutex() locked
void EffectChain::process_l()
{
    // never process effects when:
@@ -2259,7 +2259,7 @@ status_t EffectChain::createEffect_l(sp<IAfEffectModule>& effect,
                                                   audio_session_t sessionId,
                                                   bool pinned)
{
    Mutex::Autolock _l(mLock);
    audio_utils::lock_guard _l(mutex());
    effect = new EffectModule(mEffectCallback, desc, id, sessionId, pinned, AUDIO_PORT_HANDLE_NONE);
    status_t lStatus = effect->status();
    if (lStatus == NO_ERROR) {
@@ -2274,10 +2274,10 @@ status_t EffectChain::createEffect_l(sp<IAfEffectModule>& effect,
// addEffect_l() must be called with IAfThreadBase::mutex() held
status_t EffectChain::addEffect_l(const sp<IAfEffectModule>& effect)
{
    Mutex::Autolock _l(mLock);
    audio_utils::lock_guard _l(mutex());
    return addEffect_ll(effect);
}
// addEffect_l() must be called with IAfThreadBase::mLock and EffectChain::mutex() held
// addEffect_l() must be called with IAfThreadBase::mutex() and EffectChain::mutex() held
status_t EffectChain::addEffect_ll(const sp<IAfEffectModule>& effect)
{
    effect->setCallback(mEffectCallback);
@@ -2444,7 +2444,7 @@ ssize_t EffectChain::getInsertIndex(const effect_descriptor_t& desc) {
size_t EffectChain::removeEffect_l(const sp<IAfEffectModule>& effect,
                                                 bool release)
{
    Mutex::Autolock _l(mLock);
    audio_utils::lock_guard _l(mutex());
    size_t size = mEffects.size();
    uint32_t type = effect->desc().flags & EFFECT_FLAG_TYPE_MASK;

@@ -2531,7 +2531,7 @@ bool EffectChain::hasVolumeControlEnabled_l() const {
    return false;
}

// setVolume_l() must be called with IAfThreadBase::mLock or EffectChain::mLock held
// setVolume_l() must be called with IAfThreadBase::mutex() or EffectChain::mutex() held
bool EffectChain::setVolume_l(uint32_t *left, uint32_t *right, bool force)
{
    uint32_t newLeft = *left;
@@ -2607,7 +2607,7 @@ bool EffectChain::setVolume_l(uint32_t *left, uint32_t *right, bool force)
    return volumeControlIndex.has_value();
}

// resetVolume_l() must be called with IAfThreadBase::mutex() or EffectChain::mLock held
// resetVolume_l() must be called with IAfThreadBase::mutex() or EffectChain::mutex() held
void EffectChain::resetVolume_l()
{
    if ((mLeftVolume != UINT_MAX) && (mRightVolume != UINT_MAX)) {
@@ -2618,7 +2618,7 @@ void EffectChain::resetVolume_l()
}

// containsHapticGeneratingEffect_l must be called with
// IAfThreadBase::mutex() or EffectChain::mLock held
// IAfThreadBase::mutex() or EffectChain::mutex() held
bool EffectChain::containsHapticGeneratingEffect_l()
{
    for (size_t i = 0; i < mEffects.size(); ++i) {
@@ -2631,7 +2631,7 @@ bool EffectChain::containsHapticGeneratingEffect_l()

void EffectChain::setHapticIntensity_l(int id, os::HapticScale intensity)
{
    Mutex::Autolock _l(mLock);
    audio_utils::lock_guard _l(mutex());
    for (size_t i = 0; i < mEffects.size(); ++i) {
        mEffects[i]->setHapticIntensity(id, intensity);
    }
@@ -2639,7 +2639,7 @@ void EffectChain::setHapticIntensity_l(int id, os::HapticScale intensity)

void EffectChain::syncHalEffectsState()
{
    Mutex::Autolock _l(mLock);
    audio_utils::lock_guard _l(mutex());
    for (size_t i = 0; i < mEffects.size(); i++) {
        if (mEffects[i]->state() == EffectModule::ACTIVE ||
                mEffects[i]->state() == EffectModule::STOPPING) {
@@ -2657,7 +2657,7 @@ NO_THREAD_SAFETY_ANALYSIS // conditional try lock
    result.appendFormat("    %zu effects for session %d\n", numEffects, mSessionId);

    if (numEffects) {
        const bool locked = afutils::dumpTryLock(mLock);
        const bool locked = afutils::dumpTryLock(mutex());
        // failed to lock - AudioFlinger is probably deadlocked
        if (!locked) {
            result.append("\tCould not lock mutex:\n");
@@ -2680,7 +2680,7 @@ NO_THREAD_SAFETY_ANALYSIS // conditional try lock
        }

        if (locked) {
            mLock.unlock();
            mutex().unlock();
        }
    } else {
        write(fd, result.c_str(), result.size());
@@ -2729,12 +2729,12 @@ void EffectChain::setEffectSuspended_l(
                sp<IAfEffectModule> effect = desc->mEffect.promote();
                if (effect != 0) {
                    effect->setSuspended(false);
                    effect->lock();
                    effect->mutex().lock();
                    IAfEffectHandle *handle = effect->controlHandle_l();
                    if (handle != NULL && !handle->disconnected()) {
                        effect->setEnabled_l(handle->enabled());
                    }
                    effect->unlock();
                    effect->mutex().unlock();
                }
                desc->mEffect.clear();
            }
@@ -2884,7 +2884,7 @@ void EffectChain::checkSuspendOnEffectEnabled(const sp<IAfEffectModule>& effect,

bool EffectChain::isNonOffloadableEnabled() const
{
    Mutex::Autolock _l(mLock);
    audio_utils::lock_guard _l(mutex());
    return isNonOffloadableEnabled_l();
}

@@ -2901,7 +2901,7 @@ bool EffectChain::isNonOffloadableEnabled_l() const

void EffectChain::setThread(const sp<IAfThreadBase>& thread)
{
    Mutex::Autolock _l(mLock);
    audio_utils::lock_guard _l(mutex());
    mEffectCallback->setThread(thread);
}

@@ -2930,7 +2930,7 @@ void EffectChain::checkInputFlagCompatibility(audio_input_flags_t *flags) const

bool EffectChain::isRawCompatible() const
{
    Mutex::Autolock _l(mLock);
    audio_utils::lock_guard _l(mutex());
    for (const auto &effect : mEffects) {
        if (effect->isProcessImplemented()) {
            return false;
@@ -2942,7 +2942,7 @@ bool EffectChain::isRawCompatible() const

bool EffectChain::isFastCompatible() const
{
    Mutex::Autolock _l(mLock);
    audio_utils::lock_guard _l(mutex());
    for (const auto &effect : mEffects) {
        if (effect->isProcessImplemented()
                && effect->isImplementationSoftware()) {
@@ -2954,7 +2954,7 @@ bool EffectChain::isFastCompatible() const
}

bool EffectChain::isBitPerfectCompatible() const {
    Mutex::Autolock _l(mLock);
    audio_utils::lock_guard _l(mutex());
    for (const auto &effect : mEffects) {
        if (effect->isProcessImplemented()
                && effect->isImplementationSoftware()) {
@@ -2965,10 +2965,10 @@ bool EffectChain::isBitPerfectCompatible() const {
    return true;
}

// isCompatibleWithThread_l() must be called with thread->mLock held
// isCompatibleWithThread_l() must be called with thread->mutex() held
bool EffectChain::isCompatibleWithThread_l(const sp<IAfThreadBase>& thread) const
{
    Mutex::Autolock _l(mLock);
    audio_utils::lock_guard _l(mutex());
    for (size_t i = 0; i < mEffects.size(); i++) {
        if (thread->checkEffectCompatibility_l(&(mEffects[i]->desc()), mSessionId) != NO_ERROR) {
            return false;
@@ -3272,7 +3272,7 @@ sp<IAfDeviceEffectProxy> IAfDeviceEffectProxy::create(
status_t DeviceEffectProxy::setEnabled(bool enabled, bool fromHandle)
{
    status_t status = EffectBase::setEnabled(enabled, fromHandle);
    Mutex::Autolock _l(mProxyLock);
    audio_utils::lock_guard _l(proxyMutex());
    if (status == NO_ERROR) {
        for (auto& handle : mEffectHandles) {
            Status bs;
@@ -3325,7 +3325,7 @@ status_t DeviceEffectProxy::onCreatePatch(
        ALOGV("%s sink %d checkPort status %d", __func__, i, status);
    }
    if (status == NO_ERROR || status == ALREADY_EXISTS) {
        Mutex::Autolock _l(mProxyLock);
        audio_utils::lock_guard _l(proxyMutex());
        mEffectHandles.emplace(patchHandle, handle);
    }
    ALOGW_IF(status == BAD_VALUE,
@@ -3357,7 +3357,7 @@ status_t DeviceEffectProxy::checkPort(const IAfPatchPanel::Patch& patch,
    status_t status = NAME_NOT_FOUND;

    if (mDescriptor.flags & EFFECT_FLAG_HW_ACC_TUNNEL) {
        Mutex::Autolock _l(mProxyLock);
        audio_utils::lock_guard _l(proxyMutex());
        mDevicePort = *port;
        mHalEffect = new EffectModule(mMyCallback,
                                      const_cast<effect_descriptor_t *>(&mDescriptor),
@@ -3421,7 +3421,7 @@ status_t DeviceEffectProxy::checkPort(const IAfPatchPanel::Patch& patch,
void DeviceEffectProxy::onReleasePatch(audio_patch_handle_t patchHandle) {
    sp<IAfEffectHandle> effect;
    {
        Mutex::Autolock _l(mProxyLock);
        audio_utils::lock_guard _l(proxyMutex());
        if (mEffectHandles.find(patchHandle) != mEffectHandles.end()) {
            effect = mEffectHandles.at(patchHandle);
            mEffectHandles.erase(patchHandle);
@@ -3432,7 +3432,7 @@ void DeviceEffectProxy::onReleasePatch(audio_patch_handle_t patchHandle) {

size_t DeviceEffectProxy::removeEffect(const sp<IAfEffectModule>& effect)
{
    Mutex::Autolock _l(mProxyLock);
    audio_utils::lock_guard _l(proxyMutex());
    if (effect == mHalEffect) {
        mHalEffect->release_l();
        mHalEffect.clear();
@@ -3493,7 +3493,7 @@ NO_THREAD_SAFETY_ANALYSIS // conditional try lock
    const Vector<String16> args;
    EffectBase::dump(fd, args);

    const bool locked = afutils::dumpTryLock(mProxyLock);
    const bool locked = afutils::dumpTryLock(proxyMutex());
    if (!locked) {
        String8 result("DeviceEffectProxy may be deadlocked\n");
        write(fd, result.c_str(), result.size());
@@ -3523,7 +3523,7 @@ NO_THREAD_SAFETY_ANALYSIS // conditional try lock
    }

    if (locked) {
        mLock.unlock();
        proxyMutex().unlock();
    }
}

+19 −19
Original line number Diff line number Diff line
@@ -111,8 +111,7 @@ public:
    bool             isPinned() const final { return mPinned; }
    void             unPin() final { mPinned = false; }

    void             lock() ACQUIRE(mLock) final { mLock.lock(); }
    void             unlock() RELEASE(mLock) final { mLock.unlock(); }
    audio_utils::mutex& mutex() const final { return mMutex; }

    status_t         updatePolicyState() final;

@@ -135,7 +134,8 @@ protected:

    DISALLOW_COPY_AND_ASSIGN(EffectBase);

    mutable Mutex mLock;      // mutex for process, commands and handles list protection
    // mutex for process, commands and handles list protection
    mutable audio_utils::mutex mMutex;
    mediautils::atomic_sp<EffectCallbackInterface> mCallback; // parent effect chain
    const int                 mId;        // this instance unique ID
    const audio_session_t     mSessionId; // audio session ID
@@ -148,9 +148,10 @@ protected:
                // First handle in mHandles has highest priority and controls the effect module

    // Audio policy effect state management
    // Mutex protecting transactions with audio policy manager as mLock cannot
    // Mutex protecting transactions with audio policy manager as mutex() cannot
    // be held to avoid cross deadlocks with audio policy mutex
    Mutex                     mPolicyLock;
    audio_utils::mutex& policyMutex() const { return mPolicyMutex; }
    mutable audio_utils::mutex mPolicyMutex;
    // Effect is registered in APM or not
    bool                      mPolicyRegistered = false;
    // Effect enabled state communicated to APM. Enabled state corresponds to
@@ -272,9 +273,10 @@ private:
    uint32_t mInChannelCountRequested;
    uint32_t mOutChannelCountRequested;

    template <typename MUTEX>
    class AutoLockReentrant {
    public:
        AutoLockReentrant(Mutex& mutex, pid_t allowedTid)
        AutoLockReentrant(MUTEX& mutex, pid_t allowedTid)
            : mMutex(gettid() == allowedTid ? nullptr : &mutex)
        {
            if (mMutex != nullptr) mMutex->lock();
@@ -283,7 +285,7 @@ private:
            if (mMutex != nullptr) mMutex->unlock();
        }
    private:
        Mutex * const mMutex;
        MUTEX * const mMutex;
    };

    static constexpr pid_t INVALID_PID = (pid_t)-1;
@@ -364,7 +366,8 @@ private:
private:
    DISALLOW_COPY_AND_ASSIGN(EffectHandle);

    Mutex mLock;                             // protects IEffect method calls
    audio_utils::mutex& mutex() const { return mMutex; }
    mutable audio_utils::mutex mMutex; // protects IEffect method calls
    const wp<IAfEffectBase> mEffect;               // pointer to controlled EffectModule
    const sp<media::IEffectClient> mEffectClient;  // callback interface for client notifications
    /*const*/ sp<Client> mClient;            // client for shared memory allocation, see
@@ -397,12 +400,8 @@ public:

    void process_l() final;

    void lock() ACQUIRE(mLock) final {
        mLock.lock();
    }
    void unlock() RELEASE(mLock) final {
        mLock.unlock();
    }
    audio_utils::mutex& mutex() const final { return mMutex; }

    status_t createEffect_l(sp<IAfEffectModule>& effect,
                            effect_descriptor_t *desc,
                            int id,
@@ -488,7 +487,7 @@ public:
    // Is this EffectChain compatible with the bit-perfect audio flag.
    bool isBitPerfectCompatible() const final;

    // isCompatibleWithThread_l() must be called with thread->mLock held
    // isCompatibleWithThread_l() must be called with thread->mutex() held
    bool isCompatibleWithThread_l(const sp<IAfThreadBase>& thread) const final;

    bool containsHapticGeneratingEffect_l() final;
@@ -624,7 +623,7 @@ private:

    std::optional<size_t> findVolumeControl_l(size_t from, size_t to) const;

    mutable  Mutex mLock;        // mutex protecting effect list
    mutable audio_utils::mutex mMutex; // mutex protecting effect list
             Vector<sp<IAfEffectModule>> mEffects; // list of effect modules
             audio_session_t mSessionId; // audio session ID
             sp<EffectBufferHalInterface> mInBuffer;  // chain input buffer
@@ -754,9 +753,10 @@ private:
    const sp<DeviceEffectManagerCallback> mManagerCallback;
    const sp<ProxyCallback> mMyCallback;

    mutable Mutex mProxyLock;
    std::map<audio_patch_handle_t, sp<IAfEffectHandle>> mEffectHandles; // protected by mProxyLock
    sp<IAfEffectModule> mHalEffect; // protected by mProxyLock
    audio_utils::mutex& proxyMutex() const { return mProxyMutex; }
    mutable audio_utils::mutex mProxyMutex;
    std::map<audio_patch_handle_t, sp<IAfEffectHandle>> mEffectHandles; // protected by mProxyMutex
    sp<IAfEffectModule> mHalEffect; // protected by mProxyMutex
    struct audio_port_config mDevicePort = { .id = AUDIO_PORT_HANDLE_NONE };
    const bool mNotifyFramesProcessed;
};
Loading