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

Commit 2bc0be83 authored by Shunkai Yao's avatar Shunkai Yao
Browse files

Refine EffectProxy logic

To allow create multiple EffectProxy instances for same type
Implement dump with all sub-effects

Bug: 271500140
Test: Enable AIDL and flash to pixel
Test: Play Youtube music with effect on/off
Test: dumpsys media.audio_flinger

Change-Id: I468d7e8712d7b098d869f147a4b40881ef11cabb
parent e48df3c5
Loading
Loading
Loading
Loading
+24 −14
Original line number Original line Diff line number Diff line
@@ -194,11 +194,9 @@ status_t EffectConversionHelperAidl::handleSetConfig(uint32_t cmdSize, const voi
                statusTFromBinderStatus(mEffect->open(common, std::nullopt, &openReturn)));
                statusTFromBinderStatus(mEffect->open(common, std::nullopt, &openReturn)));


        if (mIsProxyEffect) {
        if (mIsProxyEffect) {
            const auto& ret =
            mStatusQ = std::static_pointer_cast<EffectProxy>(mEffect)->getStatusMQ();
                    std::static_pointer_cast<EffectProxy>(mEffect)->getEffectReturnParam();
            mInputQ = std::static_pointer_cast<EffectProxy>(mEffect)->getInputMQ();
            mStatusQ = std::make_shared<StatusMQ>(ret->statusMQ);
            mOutputQ = std::static_pointer_cast<EffectProxy>(mEffect)->getOutputMQ();
            mInputQ = std::make_shared<DataMQ>(ret->inputDataMQ);
            mOutputQ = std::make_shared<DataMQ>(ret->outputDataMQ);
        } else {
        } else {
            mStatusQ = std::make_shared<StatusMQ>(openReturn.statusMQ);
            mStatusQ = std::make_shared<StatusMQ>(openReturn.statusMQ);
            mInputQ = std::make_shared<DataMQ>(openReturn.inputDataMQ);
            mInputQ = std::make_shared<DataMQ>(openReturn.inputDataMQ);
@@ -206,6 +204,7 @@ status_t EffectConversionHelperAidl::handleSetConfig(uint32_t cmdSize, const voi
        }
        }


        if (status_t status = updateEventFlags(); status != OK) {
        if (status_t status = updateEventFlags(); status != OK) {
            ALOGV("%s closing at status %d", __func__, status);
            mEffect->close();
            mEffect->close();
            return status;
            return status;
        }
        }
@@ -353,14 +352,15 @@ status_t EffectConversionHelperAidl::handleSetOffload(uint32_t cmdSize, const vo
        ALOGI("%s offload param offload %s ioHandle %d", __func__,
        ALOGI("%s offload param offload %s ioHandle %d", __func__,
              offload->isOffload ? "true" : "false", offload->ioHandle);
              offload->isOffload ? "true" : "false", offload->ioHandle);
        mCommon.ioHandle = offload->ioHandle;
        mCommon.ioHandle = offload->ioHandle;
        RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
        const auto& effectProxy = std::static_pointer_cast<EffectProxy>(mEffect);
                std::static_pointer_cast<EffectProxy>(mEffect)->setOffloadParam(offload)));
        RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(effectProxy->setOffloadParam(offload)));
        // update FMQs
        // update FMQs if the effect instance already open
        const auto& ret = std::static_pointer_cast<EffectProxy>(mEffect)->getEffectReturnParam();
        if (State state; effectProxy->getState(&state).isOk() && state != State::INIT) {
        mStatusQ = std::make_shared<StatusMQ>(ret->statusMQ);
            mStatusQ = effectProxy->getStatusMQ();
        mInputQ = std::make_shared<DataMQ>(ret->inputDataMQ);
            mInputQ = effectProxy->getInputMQ();
        mOutputQ = std::make_shared<DataMQ>(ret->outputDataMQ);
            mOutputQ = effectProxy->getOutputMQ();
        RETURN_STATUS_IF_ERROR(updateEventFlags());
            updateEventFlags();
        }
    }
    }
    return *static_cast<int32_t*>(pReplyData) = OK;
    return *static_cast<int32_t*>(pReplyData) = OK;
}
}
@@ -408,17 +408,27 @@ status_t EffectConversionHelperAidl::handleVisualizerMeasure(uint32_t cmdSize __
status_t EffectConversionHelperAidl::updateEventFlags() {
status_t EffectConversionHelperAidl::updateEventFlags() {
    status_t status = BAD_VALUE;
    status_t status = BAD_VALUE;
    EventFlag* efGroup = nullptr;
    EventFlag* efGroup = nullptr;
    if (mStatusQ->isValid()) {
    if (mStatusQ && mStatusQ->isValid()) {
        status = EventFlag::createEventFlag(mStatusQ->getEventFlagWord(), &efGroup);
        status = EventFlag::createEventFlag(mStatusQ->getEventFlagWord(), &efGroup);
        if (status != OK || !efGroup) {
        if (status != OK || !efGroup) {
            ALOGE("%s: create EventFlagGroup failed, ret %d, egGroup %p", __func__, status,
            ALOGE("%s: create EventFlagGroup failed, ret %d, egGroup %p", __func__, status,
                  efGroup);
                  efGroup);
            status = (status == OK) ? BAD_VALUE : status;
            status = (status == OK) ? BAD_VALUE : status;
        }
        }
    } else if (isBypassing()) {
        // for effect with bypass (no processing) flag, it's okay to not have statusQ
        return OK;
    }
    }

    mEfGroup.reset(efGroup, EventFlagDeleter());
    mEfGroup.reset(efGroup, EventFlagDeleter());
    return status;
    return status;
}
}


bool EffectConversionHelperAidl::isBypassing() const {
    return mEffect &&
           (mDesc.common.flags.bypass ||
            (mIsProxyEffect && std::static_pointer_cast<EffectProxy>(mEffect)->isBypassing()));
}

}  // namespace effect
}  // namespace effect
}  // namespace android
}  // namespace android
+1 −0
Original line number Original line Diff line number Diff line
@@ -41,6 +41,7 @@ class EffectConversionHelperAidl {
    std::shared_ptr<DataMQ> getInputMQ() { return mInputQ; }
    std::shared_ptr<DataMQ> getInputMQ() { return mInputQ; }
    std::shared_ptr<DataMQ> getOutputMQ() { return mOutputQ; }
    std::shared_ptr<DataMQ> getOutputMQ() { return mOutputQ; }
    std::shared_ptr<android::hardware::EventFlag> getEventFlagGroup() { return mEfGroup; }
    std::shared_ptr<android::hardware::EventFlag> getEventFlagGroup() { return mEfGroup; }
    bool isBypassing() const;


  protected:
  protected:
    const int32_t mSessionId;
    const int32_t mSessionId;
+8 −2
Original line number Original line Diff line number Diff line
@@ -76,8 +76,11 @@ EffectHalAidl::EffectHalAidl(const std::shared_ptr<IFactory>& factory,


EffectHalAidl::~EffectHalAidl() {
EffectHalAidl::~EffectHalAidl() {
    if (mEffect) {
    if (mEffect) {
        mIsProxyEffect ? std::static_pointer_cast<EffectProxy>(mEffect)->destroy()
        if (mIsProxyEffect) {
                       : mFactory->destroyEffect(mEffect);
            std::static_pointer_cast<EffectProxy>(mEffect)->destroy();
        } else if (mFactory) {
            mFactory->destroyEffect(mEffect);
        }
    }
    }
}
}


@@ -167,6 +170,9 @@ status_t EffectHalAidl::process() {
    auto inputQ = mConversion->getInputMQ();
    auto inputQ = mConversion->getInputMQ();
    auto outputQ = mConversion->getOutputMQ();
    auto outputQ = mConversion->getOutputMQ();
    auto efGroup = mConversion->getEventFlagGroup();
    auto efGroup = mConversion->getEventFlagGroup();
    if (mConversion->isBypassing()) {
        return OK;
    }
    if (!statusQ || !statusQ->isValid() || !inputQ || !inputQ->isValid() || !outputQ ||
    if (!statusQ || !statusQ->isValid() || !inputQ || !inputQ->isValid() || !outputQ ||
        !outputQ->isValid() || !efGroup) {
        !outputQ->isValid() || !efGroup) {
        ALOGE("%s invalid FMQ [Status %d I %d O %d] efGroup %p", __func__,
        ALOGE("%s invalid FMQ [Status %d I %d O %d] efGroup %p", __func__,
+135 −127
Original line number Original line Diff line number Diff line
@@ -15,6 +15,7 @@
 */
 */


#include <algorithm>
#include <algorithm>
#include <iterator>
#include <memory>
#include <memory>
#define LOG_TAG "EffectProxy"
#define LOG_TAG "EffectProxy"
// #define LOG_NDEBUG 0
// #define LOG_NDEBUG 0
@@ -25,6 +26,7 @@


#include "EffectProxy.h"
#include "EffectProxy.h"


using ::aidl::android::hardware::audio::effect::Capability;
using ::aidl::android::hardware::audio::effect::CommandId;
using ::aidl::android::hardware::audio::effect::CommandId;
using ::aidl::android::hardware::audio::effect::Descriptor;
using ::aidl::android::hardware::audio::effect::Descriptor;
using ::aidl::android::hardware::audio::effect::Flags;
using ::aidl::android::hardware::audio::effect::Flags;
@@ -33,19 +35,29 @@ using ::aidl::android::hardware::audio::effect::IFactory;
using ::aidl::android::hardware::audio::effect::Parameter;
using ::aidl::android::hardware::audio::effect::Parameter;
using ::aidl::android::hardware::audio::effect::State;
using ::aidl::android::hardware::audio::effect::State;
using ::aidl::android::media::audio::common::AudioUuid;
using ::aidl::android::media::audio::common::AudioUuid;
using ::android::audio::utils::toString;


namespace android::effect {
namespace android {

namespace effect {
EffectProxy::EffectProxy(const AudioUuid& uuid, const std::vector<Descriptor>& descriptors,

                         const std::shared_ptr<IFactory>& factory)
EffectProxy::EffectProxy(const Descriptor::Identity& id, const std::shared_ptr<IFactory>& factory)
    : mDescriptorCommon(buildDescriptorCommon(uuid, descriptors)),
    : mIdentity([](const Descriptor::Identity& subId) {
      mSubEffects(
          // update EffectProxy implementation UUID to the sub-effect proxy UUID
              [](const std::vector<Descriptor>& descs, const std::shared_ptr<IFactory>& factory) {
          ALOG_ASSERT(subId.proxy.has_value(), "Sub-effect Identity must have valid proxy UUID");
                  std::vector<SubEffect> subEffects;
          Descriptor::Identity tempId = subId;
                  ALOG_ASSERT(factory, "invalid EffectFactory handle");
          tempId.uuid = subId.proxy.value();
                  ndk::ScopedAStatus status = ndk::ScopedAStatus::ok();
          return tempId;
                  for (const auto& desc : descs) {
      }(id)),
                      SubEffect sub({.descriptor = desc});
                      status = factory->createEffect(desc.common.id.uuid, &sub.handle);
                      if (!status.isOk() || !sub.handle) {
                          sub.handle = nullptr;
                          ALOGW("%s create sub-effect %s failed", __func__,
                                ::android::audio::utils::toString(desc.common.id.uuid).c_str());
                      }
                      subEffects.emplace_back(sub);
                  }
                  return subEffects;
              }(descriptors, factory)),
      mFactory(factory) {}
      mFactory(factory) {}


EffectProxy::~EffectProxy() {
EffectProxy::~EffectProxy() {
@@ -54,68 +66,9 @@ EffectProxy::~EffectProxy() {
    mSubEffects.clear();
    mSubEffects.clear();
}
}


// sub effect must have same proxy UUID as EffectProxy, and the type UUID must match.
ndk::ScopedAStatus EffectProxy::addSubEffect(const Descriptor& sub) {
    ALOGV("%s: %s", __func__, toString(mIdentity.type).c_str());
    if (0 != mSubEffects.count(sub.common.id) || !sub.common.id.proxy.has_value() ||
        sub.common.id.proxy.value() != mIdentity.uuid) {
        ALOGE("%s sub effect already exist or mismatch %s", __func__, sub.toString().c_str());
        return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
                                                                "illegalSubEffect");
    }

    // not create sub-effect yet
    std::get<SubEffectTupleIndex::HANDLE>(mSubEffects[sub.common.id]) = nullptr;
    std::get<SubEffectTupleIndex::DESCRIPTOR>(mSubEffects[sub.common.id]) = sub;
    // set the last added sub-effect to active before setOffloadParam()
    mActiveSub = sub.common.id;
    ALOGI("%s add %s to proxy %s flag %s", __func__, mActiveSub.toString().c_str(),
          mIdentity.toString().c_str(), sub.common.flags.toString().c_str());

    if (sub.common.flags.hwAcceleratorMode == Flags::HardwareAccelerator::TUNNEL) {
        mSubFlags.hwAcceleratorMode = Flags::HardwareAccelerator::TUNNEL;
    }

    // initial flag values before we know which sub-effect to active (with setOffloadParam)
    // same as HIDL EffectProxy flags
    mSubFlags.type = Flags::Type::INSERT;
    mSubFlags.insert = Flags::Insert::LAST;
    mSubFlags.volume = Flags::Volume::CTRL;

    // set indication if any sub-effect indication was set
    mSubFlags.offloadIndication |= sub.common.flags.offloadIndication;
    mSubFlags.deviceIndication |= sub.common.flags.deviceIndication;
    mSubFlags.audioModeIndication |= sub.common.flags.audioModeIndication;
    mSubFlags.audioSourceIndication |= sub.common.flags.audioSourceIndication;

    // set bypass when all sub-effects are bypassing
    mSubFlags.bypass &= sub.common.flags.bypass;
    return ndk::ScopedAStatus::ok();
}

ndk::ScopedAStatus EffectProxy::create() {
    ALOGV("%s: %s", __func__, toString(mIdentity.type).c_str());
    ndk::ScopedAStatus status = ndk::ScopedAStatus::ok();

    for (auto& sub : mSubEffects) {
        auto& effectHandle = std::get<SubEffectTupleIndex::HANDLE>(sub.second);
        ALOGI("%s sub-effect %s", __func__, toString(sub.first.uuid).c_str());
        status = mFactory->createEffect(sub.first.uuid, &effectHandle);
        if (!status.isOk() || !effectHandle) {
            ALOGE("%s sub-effect failed %s", __func__, toString(sub.first.uuid).c_str());
            break;
        }
    }

    // destroy all created effects if failure
    if (!status.isOk()) {
        destroy();
    }
    return status;
}

ndk::ScopedAStatus EffectProxy::destroy() {
ndk::ScopedAStatus EffectProxy::destroy() {
    ALOGV("%s: %s", __func__, toString(mIdentity.type).c_str());
    ALOGV("%s: %s", __func__,
          ::android::audio::utils::toString(mDescriptorCommon.id.type).c_str());
    return runWithAllSubEffects([&](std::shared_ptr<IEffect>& effect) {
    return runWithAllSubEffects([&](std::shared_ptr<IEffect>& effect) {
        ndk::ScopedAStatus status = mFactory->destroyEffect(effect);
        ndk::ScopedAStatus status = mFactory->destroyEffect(effect);
        if (status.isOk()) {
        if (status.isOk()) {
@@ -125,28 +78,24 @@ ndk::ScopedAStatus EffectProxy::destroy() {
    });
    });
}
}


const IEffect::OpenEffectReturn* EffectProxy::getEffectReturnParam() {
    return &std::get<SubEffectTupleIndex::RETURN>(mSubEffects[mActiveSub]);
}

ndk::ScopedAStatus EffectProxy::setOffloadParam(const effect_offload_param_t* offload) {
ndk::ScopedAStatus EffectProxy::setOffloadParam(const effect_offload_param_t* offload) {
    const auto& itor = std::find_if(mSubEffects.begin(), mSubEffects.end(), [&](const auto& sub) {
    const auto& itor = std::find_if(mSubEffects.begin(), mSubEffects.end(), [&](const auto& sub) {
        const auto& desc = std::get<SubEffectTupleIndex::DESCRIPTOR>(sub.second);
        const auto& desc = sub.descriptor;
        ALOGI("%s: isOffload %d sub-effect: %s, flags %s", __func__, offload->isOffload,
              toString(desc.common.id.uuid).c_str(), desc.common.flags.toString().c_str());
        return offload->isOffload ==
        return offload->isOffload ==
               (desc.common.flags.hwAcceleratorMode == Flags::HardwareAccelerator::TUNNEL);
               (desc.common.flags.hwAcceleratorMode == Flags::HardwareAccelerator::TUNNEL);
    });
    });
    if (itor == mSubEffects.end()) {
    if (itor == mSubEffects.end()) {
        ALOGE("%s no %soffload sub-effect found", __func__, offload->isOffload ? "" : "non-");
        ALOGE("%s no %soffload sub-effect found", __func__, offload->isOffload ? "" : "non-");
        mActiveSubIdx = 0;
        return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_NULL_POINTER,
        return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_NULL_POINTER,
                                                                "noActiveEffctFound");
                                                                "noActiveEffctFound");
    }
    }


    mActiveSub = itor->first;
    mActiveSubIdx = std::distance(mSubEffects.begin(), itor);
    ALOGI("%s: active %soffload sub-effect: %s, flags %s", __func__,
    ALOGV("%s: active %soffload sub-effect %zu descriptor: %s", __func__,
          offload->isOffload ? "" : "non-", toString(mActiveSub.uuid).c_str(),
          offload->isOffload ? "" : "non-", mActiveSubIdx,
          std::get<SubEffectTupleIndex::DESCRIPTOR>(itor->second).common.flags.toString().c_str());
          ::android::audio::utils::toString(mSubEffects[mActiveSubIdx].descriptor.common.id.uuid)
                  .c_str());
    return ndk::ScopedAStatus::ok();
    return ndk::ScopedAStatus::ok();
}
}


@@ -154,20 +103,24 @@ ndk::ScopedAStatus EffectProxy::setOffloadParam(const effect_offload_param_t* of
ndk::ScopedAStatus EffectProxy::open(const Parameter::Common& common,
ndk::ScopedAStatus EffectProxy::open(const Parameter::Common& common,
                                     const std::optional<Parameter::Specific>& specific,
                                     const std::optional<Parameter::Specific>& specific,
                                     IEffect::OpenEffectReturn* ret __unused) {
                                     IEffect::OpenEffectReturn* ret __unused) {
    ALOGV("%s: %s", __func__, toString(mIdentity.type).c_str());
    ndk::ScopedAStatus status = ndk::ScopedAStatus::fromExceptionCodeWithMessage(
    ndk::ScopedAStatus status = ndk::ScopedAStatus::fromExceptionCodeWithMessage(
            EX_ILLEGAL_ARGUMENT, "nullEffectHandle");
            EX_ILLEGAL_ARGUMENT, "nullEffectHandle");
    for (auto& sub : mSubEffects) {
    for (auto& sub : mSubEffects) {
        auto& effect = std::get<SubEffectTupleIndex::HANDLE>(sub.second);
        IEffect::OpenEffectReturn openReturn;
        auto& openRet = std::get<SubEffectTupleIndex::RETURN>(sub.second);
        if (!sub.handle || !(status = sub.handle->open(common, specific, &openReturn)).isOk()) {
        if (!effect || !(status = effect->open(common, specific, &openRet)).isOk()) {
            ALOGE("%s: failed to open %p UUID %s", __func__, sub.handle.get(),
            ALOGE("%s: failed to open UUID %s", __func__, toString(sub.first.uuid).c_str());
                  ::android::audio::utils::toString(sub.descriptor.common.id.uuid).c_str());
            break;
            break;
        }
        }
        sub.effectMq.statusQ = std::make_shared<StatusMQ>(openReturn.statusMQ);
        sub.effectMq.inputQ = std::make_shared<DataMQ>(openReturn.inputDataMQ);
        sub.effectMq.outputQ = std::make_shared<DataMQ>(openReturn.outputDataMQ);
    }
    }


    // close all opened effects if failure
    // close all opened effects if failure
    if (!status.isOk()) {
    if (!status.isOk()) {
        ALOGE("%s: closing all sub-effects with error %s", __func__,
              status.getDescription().c_str());
        close();
        close();
    }
    }


@@ -175,38 +128,69 @@ ndk::ScopedAStatus EffectProxy::open(const Parameter::Common& common,
}
}


ndk::ScopedAStatus EffectProxy::close() {
ndk::ScopedAStatus EffectProxy::close() {
    ALOGV("%s: %s", __func__, toString(mIdentity.type).c_str());
    return runWithAllSubEffects([&](std::shared_ptr<IEffect>& effect) {
    return runWithAllSubEffects([&](std::shared_ptr<IEffect>& effect) {
        return effect->close();
        return effect->close();
    });
    });
}
}


ndk::ScopedAStatus EffectProxy::getDescriptor(Descriptor* desc) {
ndk::ScopedAStatus EffectProxy::getDescriptor(Descriptor* desc) {
    desc->common = mDescriptorCommon;
    desc->capability = mSubEffects[mActiveSubIdx].descriptor.capability;
    return ndk::ScopedAStatus::ok();
}

ndk::ScopedAStatus EffectProxy::buildDescriptor(const AudioUuid& uuid,
                                                const std::vector<Descriptor>& subEffectDescs,
                                                Descriptor* desc) {
    if (!desc) {
    if (!desc) {
        ALOGE("%s: nuull descriptor pointer", __func__);
        ALOGE("%s: null descriptor pointer", __func__);
        return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_NULL_POINTER, "nullptr");
        return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_NULL_POINTER, "nullptr");
    }
    }


    auto& activeSubEffect = std::get<SubEffectTupleIndex::HANDLE>(mSubEffects[mActiveSub]);
    if (subEffectDescs.size() < 2) {
    // return initial descriptor if no active sub-effect exist
        ALOGE("%s: proxy need at least 2 sub-effects, got %zu", __func__, subEffectDescs.size());
    if (!activeSubEffect) {
        return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
        desc->common.id = mIdentity;
                                                                "needMoreSubEffects");
        desc->common.flags = mSubFlags;
        desc->common.name = "Proxy";
        desc->common.implementor = "AOSP";
    } else {
        *desc = std::get<SubEffectTupleIndex::DESCRIPTOR>(mSubEffects[mActiveSub]);
        desc->common.id = mIdentity;
    }
    }


    ALOGI("%s with %s", __func__, desc->toString().c_str());
    desc->common = buildDescriptorCommon(uuid, subEffectDescs);
    return ndk::ScopedAStatus::ok();
    return ndk::ScopedAStatus::ok();
}
}


Descriptor::Common EffectProxy::buildDescriptorCommon(
        const AudioUuid& uuid, const std::vector<Descriptor>& subEffectDescs) {
    Descriptor::Common common;

    for (const auto& desc : subEffectDescs) {
        if (desc.common.flags.hwAcceleratorMode == Flags::HardwareAccelerator::TUNNEL) {
            common.flags.hwAcceleratorMode = Flags::HardwareAccelerator::TUNNEL;
        }

        // set indication if any sub-effect indication was set
        common.flags.offloadIndication |= desc.common.flags.offloadIndication;
        common.flags.deviceIndication |= desc.common.flags.deviceIndication;
        common.flags.audioModeIndication |= desc.common.flags.audioModeIndication;
        common.flags.audioSourceIndication |= desc.common.flags.audioSourceIndication;
    }

    // initial flag values before we know which sub-effect to active (with setOffloadParam)
    // same as HIDL EffectProxy flags
    common.flags.type = Flags::Type::INSERT;
    common.flags.insert = Flags::Insert::LAST;
    common.flags.volume = Flags::Volume::CTRL;

    // copy type UUID from any of sub-effects, all sub-effects should have same type
    common.id.type = subEffectDescs[0].common.id.type;
    // replace implementation UUID with proxy UUID.
    common.id.uuid = uuid;
    common.id.proxy = std::nullopt;
    common.name = "Proxy";
    common.implementor = "AOSP";
    return common;
}

// Handle with active sub-effect first, only send to other sub-effects when success
// Handle with active sub-effect first, only send to other sub-effects when success
ndk::ScopedAStatus EffectProxy::command(CommandId id) {
ndk::ScopedAStatus EffectProxy::command(CommandId id) {
    ALOGV("%s: %s, command %s", __func__, toString(mIdentity.type).c_str(),
          android::internal::ToString(id).c_str());
    return runWithActiveSubEffectThenOthers(
    return runWithActiveSubEffectThenOthers(
            [&](const std::shared_ptr<IEffect>& effect) -> ndk::ScopedAStatus {
            [&](const std::shared_ptr<IEffect>& effect) -> ndk::ScopedAStatus {
                return effect->command(id);
                return effect->command(id);
@@ -241,34 +225,30 @@ ndk::ScopedAStatus EffectProxy::runWithActiveSubEffectThenOthers(
        std::function<ndk::ScopedAStatus(const std::shared_ptr<IEffect>&)> const& func) {
        std::function<ndk::ScopedAStatus(const std::shared_ptr<IEffect>&)> const& func) {
    ndk::ScopedAStatus status = runWithActiveSubEffect(func);
    ndk::ScopedAStatus status = runWithActiveSubEffect(func);
    if (!status.isOk()) {
    if (!status.isOk()) {
        return status;
        ALOGE("%s active sub-effect return error %s", __func__, status.getDescription().c_str());
    }
    }


    // proceed with others if active sub-effect success
    // proceed with others
    for (const auto& sub : mSubEffects) {
    for (size_t i = 0; i < mSubEffects.size() && i != mActiveSubIdx; i++) {
        auto& effect = std::get<SubEffectTupleIndex::HANDLE>(sub.second);
        if (!mSubEffects[i].handle) {
        if (sub.first != mActiveSub) {
            if (!effect) {
            ALOGE("%s null sub-effect interface for %s", __func__,
            ALOGE("%s null sub-effect interface for %s", __func__,
                      sub.first.toString().c_str());
                  mSubEffects[i].descriptor.common.id.uuid.toString().c_str());
            continue;
            continue;
        }
        }
            func(effect);
        func(mSubEffects[i].handle);
        }
    }
    }
    return status;
    return status;
}
}


ndk::ScopedAStatus EffectProxy::runWithActiveSubEffect(
ndk::ScopedAStatus EffectProxy::runWithActiveSubEffect(
        std::function<ndk::ScopedAStatus(const std::shared_ptr<IEffect>&)> const& func) {
        std::function<ndk::ScopedAStatus(const std::shared_ptr<IEffect>&)> const& func) {
    auto& effect = std::get<SubEffectTupleIndex::HANDLE>(mSubEffects[mActiveSub]);
    if (!mSubEffects[mActiveSubIdx].handle) {
    if (!effect) {
        ALOGE("%s null active sub-effect interface, active %s", __func__,
        ALOGE("%s null active sub-effect interface, active %s", __func__,
              mActiveSub.toString().c_str());
              mSubEffects[mActiveSubIdx].descriptor.toString().c_str());
        return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_NULL_POINTER,
        return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_NULL_POINTER,
                                                                "activeSubEffectNull");
                                                                "activeSubEffectNull");
    }
    }
    return func(effect);
    return func(mSubEffects[mActiveSubIdx].handle);
}
}


ndk::ScopedAStatus EffectProxy::runWithAllSubEffects(
ndk::ScopedAStatus EffectProxy::runWithAllSubEffects(
@@ -276,12 +256,11 @@ ndk::ScopedAStatus EffectProxy::runWithAllSubEffects(
    ndk::ScopedAStatus status = ndk::ScopedAStatus::ok();
    ndk::ScopedAStatus status = ndk::ScopedAStatus::ok();
    // proceed with others if active sub-effect success
    // proceed with others if active sub-effect success
    for (auto& sub : mSubEffects) {
    for (auto& sub : mSubEffects) {
        auto& effect = std::get<SubEffectTupleIndex::HANDLE>(sub.second);
        if (!sub.handle) {
        if (!effect) {
            ALOGW("%s null sub-effect interface %s", __func__, sub.descriptor.toString().c_str());
            ALOGW("%s null sub-effect interface for %s", __func__, sub.first.toString().c_str());
            continue;
            continue;
        }
        }
        ndk::ScopedAStatus temp = func(effect);
        ndk::ScopedAStatus temp = func(sub.handle);
        if (!temp.isOk()) {
        if (!temp.isOk()) {
            status = ndk::ScopedAStatus::fromStatus(temp.getStatus());
            status = ndk::ScopedAStatus::fromStatus(temp.getStatus());
        }
        }
@@ -289,5 +268,34 @@ ndk::ScopedAStatus EffectProxy::runWithAllSubEffects(
    return status;
    return status;
}
}


} // namespace effect
bool EffectProxy::isBypassing() const {
} // namespace android
    return mSubEffects[mActiveSubIdx].descriptor.common.flags.bypass;
}

binder_status_t EffectProxy::dump(int fd, const char** args, uint32_t numArgs) {
    const std::string dumpString = toString();
    write(fd, dumpString.c_str(), dumpString.size());

    return runWithAllSubEffects([&](std::shared_ptr<IEffect>& effect) {
               return ndk::ScopedAStatus::fromStatus(effect->dump(fd, args, numArgs));
           })
            .getStatus();
}

std::string EffectProxy::toString(size_t level) const {
    std::string prefixSpace(level, ' ');
    std::string ss = prefixSpace + "EffectProxy:\n";
    prefixSpace += " ";
    base::StringAppendF(&ss, "%sDescriptorCommon: %s\n", prefixSpace.c_str(),
                        mDescriptorCommon.toString().c_str());
    base::StringAppendF(&ss, "%sActiveSubIdx: %zu\n", prefixSpace.c_str(), mActiveSubIdx);
    base::StringAppendF(&ss, "%sAllSubEffects:\n", prefixSpace.c_str());
    for (size_t i = 0; i < mSubEffects.size(); i++) {
        base::StringAppendF(&ss, "%s[%zu] - Handle: %p, %s\n", prefixSpace.c_str(), i,
                            mSubEffects[i].handle.get(),
                            mSubEffects[i].descriptor.toString().c_str());
    }
    return ss;
}

} // namespace android::effect
+62 −41

File changed.

Preview size limit exceeded, changes collapsed.

Loading