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

Commit b96aa7a6 authored by Shunkai Yao's avatar Shunkai Yao Committed by Gerrit Code Review
Browse files

Merge changes I91a26704,Id77ccb0b,Ic43c375b into main

* changes:
  AudioFlinger: device effect not added to HAL
  Update mutex annotation for debug information and setVolumeInternal
  Assert effect hal interface not null before access
parents bebd4820 bf656efa
Loading
Loading
Loading
Loading
+47 −23
Original line number Diff line number Diff line
@@ -562,11 +562,8 @@ NO_THREAD_SAFETY_ANALYSIS // conditional try lock
#undef LOG_TAG
#define LOG_TAG "EffectModule"

EffectModule::EffectModule(const sp<EffectCallbackInterface>& callback,
                                         effect_descriptor_t *desc,
                                         int id,
                                         audio_session_t sessionId,
                                         bool pinned,
EffectModule::EffectModule(const sp<EffectCallbackInterface>& callback, effect_descriptor_t* desc,
                           int id, audio_session_t sessionId, bool pinned,
                           audio_port_handle_t deviceId)
    : EffectBase(callback, desc, id, sessionId, pinned),
      // clear mConfig to ensure consistent initial value of buffer framecount
@@ -577,9 +574,9 @@ EffectModule::EffectModule(const sp<EffectCallbackInterface>& callback,
      mMaxDisableWaitCnt(1), // set by configure_l(), should be >= 1
      mDisableWaitCnt(0),    // set by process() and updateState()
      mOffloaded(false),
      mIsOutput(false)
      , mSupportsFloat(false)
{
      mIsOutput(false),
      mSupportsFloat(false),
      mEffectInterfaceDebug(desc->name) {
    ALOGV("Constructor %p pinned %d", this, pinned);
    int lStatus;

@@ -587,6 +584,7 @@ EffectModule::EffectModule(const sp<EffectCallbackInterface>& callback,
    mStatus = callback->createEffectHal(
            &desc->uuid, sessionId, deviceId, &mEffectInterface);
    if (mStatus != NO_ERROR) {
        ALOGE("%s createEffectHal failed: %d", __func__, mStatus);
        return;
    }
    lStatus = init_l();
@@ -596,12 +594,14 @@ EffectModule::EffectModule(const sp<EffectCallbackInterface>& callback,
    }

    setOffloaded_l(callback->isOffload(), callback->io());
    ALOGV("Constructor success name %s, Interface %p", mDescriptor.name, mEffectInterface.get());
    ALOGV("%s Constructor success name %s, Interface %p", __func__, mDescriptor.name,
          mEffectInterface.get());

    return;
Error:
    mEffectInterface.clear();
    ALOGV("Constructor Error %d", mStatus);
    mEffectInterfaceDebug += " init failed:" + std::to_string(lStatus);
    ALOGE("%s Constructor Error %d", __func__, mStatus);
}

EffectModule::~EffectModule()
@@ -612,7 +612,7 @@ EffectModule::~EffectModule()
        AudioEffect::guidToString(&mDescriptor.uuid, uuidStr, sizeof(uuidStr));
        ALOGW("EffectModule %p destructor called with unreleased interface, effect %s",
                this, uuidStr);
        release_l();
        release_l("~EffectModule");
    }

}
@@ -1046,10 +1046,23 @@ void EffectModule::addEffectToHal_l()
            return;
        }

        (void)getCallback()->addEffectToHal(mEffectInterface);
        status_t status = getCallback()->addEffectToHal(mEffectInterface);
        if (status == NO_ERROR) {
            mCurrentHalStream = getCallback()->io();
        }
    }
}

void HwAccDeviceEffectModule::addEffectToHal_l()
{
    if (mAddedToHal) {
        return;
    }
    status_t status = getCallback()->addEffectToHal(mEffectInterface);
    if (status == NO_ERROR) {
        mAddedToHal = true;
    }
}

// start_l() must be called with EffectChain::mutex() held
status_t EffectModule::start_l()
@@ -1129,13 +1142,14 @@ status_t EffectModule::stop_ll()
}

// must be called with EffectChain::mutex() held
void EffectModule::release_l()
void EffectModule::release_l(const std::string& from)
{
    if (mEffectInterface != 0) {
        removeEffectFromHal_l();
        // release effect engine
        mEffectInterface->close();
        mEffectInterface.clear();
        mEffectInterfaceDebug += " released by: " + from;
    }
}

@@ -1152,6 +1166,16 @@ status_t EffectModule::removeEffectFromHal_l()
    return NO_ERROR;
}

status_t HwAccDeviceEffectModule::removeEffectFromHal_l()
{
    if (!mAddedToHal) {
        return NO_ERROR;
    }
    getCallback()->removeEffectFromHal(mEffectInterface);
    mAddedToHal = false;
    return NO_ERROR;
}

// round up delta valid if value and divisor are positive.
template <typename T>
static T roundUpDelta(const T &value, const T &divisor) {
@@ -1372,12 +1396,12 @@ status_t EffectModule::setVolume_l(uint32_t* left, uint32_t* right, bool control
            ((mDescriptor.flags & EFFECT_FLAG_VOLUME_MASK) == EFFECT_FLAG_VOLUME_CTRL ||
             (mDescriptor.flags & EFFECT_FLAG_VOLUME_MASK) == EFFECT_FLAG_VOLUME_IND ||
             (mDescriptor.flags & EFFECT_FLAG_VOLUME_MASK) == EFFECT_FLAG_VOLUME_MONITOR)) {
        status = setVolumeInternal(left, right, controller);
        status = setVolumeInternal_ll(left, right, controller);
    }
    return status;
}

status_t EffectModule::setVolumeInternal(
status_t EffectModule::setVolumeInternal_ll(
        uint32_t *left, uint32_t *right, bool controller) {
    if (mVolume.has_value() && *left == mVolume.value()[0] && *right == mVolume.value()[1] &&
            !controller) {
@@ -1388,6 +1412,7 @@ status_t EffectModule::setVolumeInternal(
        *right = mReturnedVolume.value()[1];
        return NO_ERROR;
    }
    LOG_ALWAYS_FATAL_IF(mEffectInterface == nullptr, "%s", mEffectInterfaceDebug.c_str());
    uint32_t volume[2] = {*left, *right};
    uint32_t* pVolume = isVolumeControl() ? volume : nullptr;
    uint32_t size = sizeof(volume);
@@ -2534,7 +2559,7 @@ size_t EffectChain::removeEffect(const sp<IAfEffectModule>& effect,
                mEffects[i]->stop_l();
            }
            if (release) {
                mEffects[i]->release_l();
                mEffects[i]->release_l("EffectChain::removeEffect");
            }
            // Skip operation when no thread attached (could lead to sigfpe as framecount is 0...)
            if (hasThreadAttached && type != EFFECT_FLAG_TYPE_AUXILIARY) {
@@ -3506,10 +3531,9 @@ NO_THREAD_SAFETY_ANALYSIS
            ALOGV("%s reusing HAL effect", __func__);
        } else {
            mDevicePort = *port;
            mHalEffect = new EffectModule(mMyCallback,
                                      const_cast<effect_descriptor_t *>(&mDescriptor),
                                      mMyCallback->newEffectId(), AUDIO_SESSION_DEVICE,
                                      false /* pinned */, port->id);
            mHalEffect = sp<HwAccDeviceEffectModule>::make(mMyCallback,
                    const_cast<effect_descriptor_t *>(&mDescriptor), mMyCallback->newEffectId(),
                    port->id);
            if (audio_is_input_device(mDevice.mType)) {
                mHalEffect->setInputDevice(mDevice);
            } else {
@@ -3581,7 +3605,7 @@ size_t DeviceEffectProxy::removeEffect(const sp<IAfEffectModule>& effect)
{
    audio_utils::lock_guard _l(proxyMutex());
    if (effect == mHalEffect) {
        mHalEffect->release_l();
        mHalEffect->release_l("DeviceEffectProxy::removeEffect");
        mHalEffect.clear();
        mDevicePort.id = AUDIO_PORT_HANDLE_NONE;
    }
+26 −9
Original line number Diff line number Diff line
@@ -179,7 +179,7 @@ protected:
// the attached track(s) to accumulate their auxiliary channel.
class EffectModule : public IAfEffectModule, public EffectBase {
public:
    EffectModule(const sp<EffectCallbackInterface>& callabck,
    EffectModule(const sp<EffectCallbackInterface>& callback,
                    effect_descriptor_t *desc,
                    int id,
                    audio_session_t sessionId,
@@ -228,8 +228,8 @@ public:
            REQUIRES(audio_utils::EffectChain_Mutex) EXCLUDES_EffectBase_Mutex;
    bool isOffloaded_l() const final
            REQUIRES(audio_utils::EffectChain_Mutex) EXCLUDES_EffectBase_Mutex;
    void addEffectToHal_l() final REQUIRES(audio_utils::EffectChain_Mutex);
    void release_l() final REQUIRES(audio_utils::EffectChain_Mutex);
    void addEffectToHal_l() override REQUIRES(audio_utils::EffectChain_Mutex);
    void release_l(const std::string& from = "") final REQUIRES(audio_utils::EffectChain_Mutex);

    sp<IAfEffectModule> asEffectModule() final { return this; }

@@ -250,6 +250,9 @@ public:

    void dump(int fd, const Vector<String16>& args) const final;

protected:
    sp<EffectHalInterface> mEffectInterface; // Effect module HAL

private:

    // Maximum time allocated to effect engines to complete the turn off sequence
@@ -259,18 +262,18 @@ private:

    status_t start_ll() REQUIRES(audio_utils::EffectChain_Mutex, audio_utils::EffectBase_Mutex);
    status_t stop_ll() REQUIRES(audio_utils::EffectChain_Mutex, audio_utils::EffectBase_Mutex);
    status_t removeEffectFromHal_l() REQUIRES(audio_utils::EffectChain_Mutex);
    status_t removeEffectFromHal_l() override REQUIRES(audio_utils::EffectChain_Mutex);
    status_t sendSetAudioDevicesCommand(const AudioDeviceTypeAddrVector &devices, uint32_t cmdCode);
    effect_buffer_access_e requiredEffectBufferAccessMode() const {
        return mConfig.inputCfg.buffer.raw == mConfig.outputCfg.buffer.raw
                ? EFFECT_BUFFER_ACCESS_WRITE : EFFECT_BUFFER_ACCESS_ACCUMULATE;
    }

    status_t setVolumeInternal(uint32_t* left, uint32_t* right,
                               bool controller /* the volume controller effect of the chain */);
    status_t setVolumeInternal_ll(uint32_t* left, uint32_t* right,
                                  bool controller /* the volume controller effect of the chain */)
            REQUIRES(audio_utils::EffectChain_Mutex, audio_utils::EffectBase_Mutex);

    effect_config_t     mConfig;    // input and output audio configuration
    sp<EffectHalInterface> mEffectInterface; // Effect module HAL
    sp<EffectBufferHalInterface> mInBuffer;  // Buffers for interacting with HAL
    sp<EffectBufferHalInterface> mOutBuffer;
    status_t            mStatus;    // initialization status
@@ -292,12 +295,12 @@ private:
    template <typename MUTEX>
    class AutoLockReentrant {
    public:
        AutoLockReentrant(MUTEX& mutex, pid_t allowedTid)
        AutoLockReentrant(MUTEX& mutex, pid_t allowedTid) ACQUIRE(audio_utils::EffectBase_Mutex)
            : mMutex(gettid() == allowedTid ? nullptr : &mutex)
        {
            if (mMutex != nullptr) mMutex->lock();
        }
        ~AutoLockReentrant() {
        ~AutoLockReentrant() RELEASE(audio_utils::EffectBase_Mutex) {
            if (mMutex != nullptr) mMutex->unlock();
        }
    private:
@@ -313,6 +316,20 @@ private:
    // Cache the volume that returned from the effect when setting volume successfully. The value
    // here is used to indicate the volume to apply before this effect.
    std::optional<std::vector<uint32_t>> mReturnedVolume;
    // TODO: b/315995877, remove this debugging string after root cause
    std::string mEffectInterfaceDebug GUARDED_BY(audio_utils::EffectChain_Mutex);
};

class HwAccDeviceEffectModule : public EffectModule {
public:
    HwAccDeviceEffectModule(const sp<EffectCallbackInterface>& callback, effect_descriptor_t *desc,
            int id, audio_port_handle_t deviceId) :
        EffectModule(callback, desc, id, AUDIO_SESSION_DEVICE, /* pinned */ false, deviceId) {}
    void addEffectToHal_l() final REQUIRES(audio_utils::EffectChain_Mutex);

private:
    status_t removeEffectFromHal_l() final REQUIRES(audio_utils::EffectChain_Mutex);
    bool mAddedToHal = false;
};

// The EffectHandle class implements the IEffect interface. It provides resources
+3 −2
Original line number Diff line number Diff line
@@ -153,7 +153,7 @@ class IAfEffectModule : public virtual IAfEffectBase {

public:
    static sp<IAfEffectModule> create(
            const sp<EffectCallbackInterface>& callabck,
            const sp<EffectCallbackInterface>& callback,
            effect_descriptor_t *desc,
            int id,
            audio_session_t sessionId,
@@ -214,7 +214,8 @@ private:

    virtual status_t stop_l() = 0;
    virtual void addEffectToHal_l() = 0;
    virtual void release_l() = 0;
    virtual status_t removeEffectFromHal_l() = 0;
    virtual void release_l(const std::string& from) = 0;
};

class IAfEffectChain : public RefBase {