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

Commit b9ab2f41 authored by Shunkai Yao's avatar Shunkai Yao Committed by Automerger Merge Worker
Browse files

Merge "Effect AIDL: queryEffect with Descriptor for all effects...

Merge "Effect AIDL: queryEffect with Descriptor for all effects implementation" am: f0a217d0 am: 8918d907 am: ace21c4c

Original change: https://android-review.googlesource.com/c/platform/hardware/interfaces/+/2344310



Change-Id: Id8b7e36cd8b4c957526aaf8ff3e0560a7cf8a24b
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents 51151afd ace21c4c
Loading
Loading
Loading
Loading
+71 −41
Original line number Diff line number Diff line
@@ -14,6 +14,10 @@
 * limitations under the License.
 */

#include <iterator>
#include <memory>
#include <tuple>
#include "include/effect-impl/EffectTypes.h"
#define LOG_TAG "AHAL_EffectFactory"
#include <dlfcn.h>
#include <unordered_set>
@@ -51,15 +55,29 @@ Factory::~Factory() {
ndk::ScopedAStatus Factory::queryEffects(const std::optional<AudioUuid>& in_type_uuid,
                                         const std::optional<AudioUuid>& in_impl_uuid,
                                         const std::optional<AudioUuid>& in_proxy_uuid,
                                         std::vector<Descriptor::Identity>* _aidl_return) {
    std::copy_if(
            mIdentitySet.begin(), mIdentitySet.end(), std::back_inserter(*_aidl_return),
            [&](auto& desc) {
                return (!in_type_uuid.has_value() || in_type_uuid.value() == desc.type) &&
                       (!in_impl_uuid.has_value() || in_impl_uuid.value() == desc.uuid) &&
                                         std::vector<Descriptor>* _aidl_return) {
    // get the matching list
    std::vector<Descriptor::Identity> idList;
    std::copy_if(mIdentitySet.begin(), mIdentitySet.end(), std::back_inserter(idList),
                 [&](auto& id) {
                     return (!in_type_uuid.has_value() || in_type_uuid.value() == id.type) &&
                            (!in_impl_uuid.has_value() || in_impl_uuid.value() == id.uuid) &&
                            (!in_proxy_uuid.has_value() ||
                        (desc.proxy.has_value() && in_proxy_uuid.value() == desc.proxy.value()));
                             (id.proxy.has_value() && in_proxy_uuid.value() == id.proxy.value()));
                 });
    // query through the matching list
    for (const auto& id : idList) {
        if (mEffectLibMap.count(id.uuid)) {
            Descriptor desc;
            auto& entry = mEffectLibMap[id.uuid];
            getDlSyms(entry);
            auto& libInterface = std::get<kMapEntryInterfaceIndex>(entry);
            RETURN_IF(!libInterface || !libInterface->queryEffectFunc, EX_NULL_POINTER,
                      "dlNullQueryEffectFunc");
            RETURN_IF_BINDER_EXCEPTION(libInterface->queryEffectFunc(&id.uuid, &desc));
            _aidl_return->emplace_back(std::move(desc));
        }
    }
    return ndk::ScopedAStatus::ok();
}

@@ -74,37 +92,16 @@ ndk::ScopedAStatus Factory::queryProcessing(const std::optional<Processing::Type
    return ndk::ScopedAStatus::ok();
}

#define RETURN_IF_BINDER_EXCEPTION(functor)                                 \
    {                                                                       \
        binder_exception_t exception = functor;                             \
        if (EX_NONE != exception) {                                         \
            LOG(ERROR) << #functor << ":  failed with error " << exception; \
            return ndk::ScopedAStatus::fromExceptionCode(exception);        \
        }                                                                   \
    }

ndk::ScopedAStatus Factory::createEffect(const AudioUuid& in_impl_uuid,
                                         std::shared_ptr<IEffect>* _aidl_return) {
    LOG(DEBUG) << __func__ << ": UUID " << in_impl_uuid.toString();
    if (mEffectLibMap.count(in_impl_uuid)) {
        auto& lib = mEffectLibMap[in_impl_uuid];
        // didn't do dlsym yet
        if (nullptr == lib.second) {
            void* libHandle = lib.first.get();
            auto dlInterface = std::make_unique<struct effect_dl_interface_s>();
            dlInterface->createEffectFunc = (EffectCreateFunctor)dlsym(libHandle, "createEffect");
            dlInterface->destroyEffectFunc =
                    (EffectDestroyFunctor)dlsym(libHandle, "destroyEffect");
            if (!dlInterface->createEffectFunc || !dlInterface->destroyEffectFunc) {
                LOG(ERROR) << __func__
                           << ": create or destroy symbol not exist in library: " << libHandle
                           << " with dlerror: " << dlerror();
                return ndk::ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED);
            }
            lib.second = std::move(dlInterface);
        }
        auto& entry = mEffectLibMap[in_impl_uuid];
        getDlSyms(entry);

        auto& libInterface = lib.second;
        auto& libInterface = std::get<kMapEntryInterfaceIndex>(entry);
        RETURN_IF(!libInterface || !libInterface->createEffectFunc, EX_NULL_POINTER,
                  "dlNullcreateEffectFunc");
        std::shared_ptr<IEffect> effectSp;
        RETURN_IF_BINDER_EXCEPTION(libInterface->createEffectFunc(&in_impl_uuid, &effectSp));
        if (!effectSp) {
@@ -131,9 +128,10 @@ ndk::ScopedAStatus Factory::destroyEffectImpl(const std::shared_ptr<IEffect>& in
        auto& uuid = uuidIt->second;
        // find implementation library with UUID
        if (auto libIt = mEffectLibMap.find(uuid); libIt != mEffectLibMap.end()) {
            if (libIt->second.second->destroyEffectFunc) {
                RETURN_IF_BINDER_EXCEPTION(libIt->second.second->destroyEffectFunc(in_handle));
            }
            auto& interface = std::get<kMapEntryInterfaceIndex>(libIt->second);
            RETURN_IF(!interface || !interface->destroyEffectFunc, EX_NULL_POINTER,
                      "dlNulldestroyEffectFunc");
            RETURN_IF_BINDER_EXCEPTION(interface->destroyEffectFunc(in_handle));
        } else {
            LOG(ERROR) << __func__ << ": UUID " << uuid.toString() << " does not exist in libMap!";
            return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
@@ -179,9 +177,13 @@ void Factory::openEffectLibrary(const AudioUuid& impl, const std::string& libNam
        return;
    }

    LOG(DEBUG) << __func__ << " dlopen lib:" << libName << "\nimpl:" << impl.toString()
    LOG(INFO) << __func__ << " dlopen lib:" << libName << "\nimpl:" << impl.toString()
              << "\nhandle:" << libHandle;
    mEffectLibMap.insert({impl, std::make_pair(std::move(libHandle), nullptr)});
    auto interface = new effect_dl_interface_s{nullptr, nullptr, nullptr};
    mEffectLibMap.insert(
            {impl,
             std::make_tuple(std::move(libHandle),
                             std::unique_ptr<struct effect_dl_interface_s>(interface), libName)});
}

void Factory::createIdentityWithConfig(const EffectConfig::LibraryUuid& configLib,
@@ -226,4 +228,32 @@ void Factory::loadEffectLibs() {
    }
}

void Factory::getDlSyms(DlEntry& entry) {
    auto& dlHandle = std::get<kMapEntryHandleIndex>(entry);
    RETURN_VALUE_IF(!dlHandle, void(), "dlNullHandle");
    // Get the reference of the DL interfaces in library map tuple.
    auto& dlInterface = std::get<kMapEntryInterfaceIndex>(entry);
    // return if interface already exist
    if (!dlInterface->createEffectFunc) {
        dlInterface->createEffectFunc = (EffectCreateFunctor)dlsym(dlHandle.get(), "createEffect");
    }
    if (!dlInterface->queryEffectFunc) {
        dlInterface->queryEffectFunc = (EffectQueryFunctor)dlsym(dlHandle.get(), "queryEffect");
    }
    if (!dlInterface->destroyEffectFunc) {
        dlInterface->destroyEffectFunc =
                (EffectDestroyFunctor)dlsym(dlHandle.get(), "destroyEffect");
    }

    if (!dlInterface->createEffectFunc || !dlInterface->destroyEffectFunc ||
        !dlInterface->queryEffectFunc) {
        LOG(ERROR) << __func__ << ": create (" << dlInterface->createEffectFunc << "), query ("
                   << dlInterface->queryEffectFunc << "), or destroy ("
                   << dlInterface->destroyEffectFunc
                   << ") not exist in library: " << std::get<kMapEntryLibNameIndex>(entry)
                   << " handle: " << dlHandle << " with dlerror: " << dlerror();
        return;
    }
}

}  // namespace aidl::android::hardware::audio::effect
+15 −0
Original line number Diff line number Diff line
@@ -19,6 +19,21 @@
#include "effect-impl/EffectTypes.h"
#include "include/effect-impl/EffectTypes.h"

using aidl::android::hardware::audio::effect::IEffect;
using aidl::android::hardware::audio::effect::State;

extern "C" binder_exception_t destroyEffect(const std::shared_ptr<IEffect>& instanceSp) {
    State state;
    ndk::ScopedAStatus status = instanceSp->getState(&state);
    if (!status.isOk() || State::INIT != state) {
        LOG(ERROR) << __func__ << " instance " << instanceSp.get()
                   << " in state: " << toString(state) << ", status: " << status.getDescription();
        return EX_ILLEGAL_STATE;
    }
    LOG(DEBUG) << __func__ << " instance " << instanceSp.get() << " destroyed";
    return EX_NONE;
}

namespace aidl::android::hardware::audio::effect {

ndk::ScopedAStatus EffectImpl::open(const Parameter::Common& common,
+21 −12
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@
#include "BassBoostSw.h"

using aidl::android::hardware::audio::effect::BassBoostSw;
using aidl::android::hardware::audio::effect::Descriptor;
using aidl::android::hardware::audio::effect::IEffect;
using aidl::android::hardware::audio::effect::kBassBoostSwImplUUID;
using aidl::android::hardware::audio::effect::State;
@@ -48,23 +49,31 @@ extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
    }
}

extern "C" binder_exception_t destroyEffect(const std::shared_ptr<IEffect>& instanceSp) {
    if (!instanceSp) {
        return EX_NONE;
    }
    State state;
    ndk::ScopedAStatus status = instanceSp->getState(&state);
    if (!status.isOk() || State::INIT != state) {
        LOG(ERROR) << __func__ << " instance " << instanceSp.get()
                   << " in state: " << toString(state) << ", status: " << status.getDescription();
        return EX_ILLEGAL_STATE;
extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
    if (!in_impl_uuid || *in_impl_uuid != kBassBoostSwImplUUID) {
        LOG(ERROR) << __func__ << "uuid not supported";
        return EX_ILLEGAL_ARGUMENT;
    }
    LOG(DEBUG) << __func__ << " instance " << instanceSp.get() << " destroyed";
    *_aidl_return = BassBoostSw::kDescriptor;
    return EX_NONE;
}

namespace aidl::android::hardware::audio::effect {

const std::string BassBoostSw::kEffectName = "BassBoostSw";
const bool BassBoostSw::kStrengthSupported = true;
const BassBoost::Capability BassBoostSw::kCapability = {.strengthSupported = kStrengthSupported};
const Descriptor BassBoostSw::kDescriptor = {
        .common = {.id = {.type = kBassBoostTypeUUID,
                          .uuid = kBassBoostSwImplUUID,
                          .proxy = std::nullopt},
                   .flags = {.type = Flags::Type::INSERT,
                             .insert = Flags::Insert::FIRST,
                             .volume = Flags::Volume::CTRL},
                   .name = BassBoostSw::kEffectName,
                   .implementor = "The Android Open Source Project"},
        .capability = Capability::make<Capability::bassBoost>(BassBoostSw::kCapability)};

ndk::ScopedAStatus BassBoostSw::getDescriptor(Descriptor* _aidl_return) {
    LOG(DEBUG) << __func__ << kDescriptor.toString();
    *_aidl_return = kDescriptor;
@@ -81,7 +90,7 @@ ndk::ScopedAStatus BassBoostSw::setParameterSpecific(const Parameter::Specific&

    switch (tag) {
        case BassBoost::strengthPm: {
            RETURN_IF(!mStrengthSupported, EX_ILLEGAL_ARGUMENT, "SettingStrengthNotSupported");
            RETURN_IF(!kStrengthSupported, EX_ILLEGAL_ARGUMENT, "SettingStrengthNotSupported");

            RETURN_IF(mContext->setBbStrengthPm(bbParam.get<BassBoost::strengthPm>()) !=
                              RetCode::SUCCESS,
+4 −16
Original line number Diff line number Diff line
@@ -51,6 +51,10 @@ class BassBoostSwContext final : public EffectContext {

class BassBoostSw final : public EffectImpl {
  public:
    static const std::string kEffectName;
    static const bool kStrengthSupported;
    static const BassBoost::Capability kCapability;
    static const Descriptor kDescriptor;
    BassBoostSw() { LOG(DEBUG) << __func__; }
    ~BassBoostSw() {
        cleanUp();
@@ -70,23 +74,7 @@ class BassBoostSw final : public EffectImpl {
    IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;

  private:
    const std::string kEffectName = "BassBoostSw";
    std::shared_ptr<BassBoostSwContext> mContext;
    /* capabilities */
    const bool mStrengthSupported = true;
    const BassBoost::Capability kCapability = {.strengthSupported = mStrengthSupported};
    /* Effect descriptor */
    const Descriptor kDescriptor = {
            .common = {.id = {.type = kBassBoostTypeUUID,
                              .uuid = kBassBoostSwImplUUID,
                              .proxy = std::nullopt},
                       .flags = {.type = Flags::Type::INSERT,
                                 .insert = Flags::Insert::FIRST,
                                 .volume = Flags::Volume::CTRL},
                       .name = kEffectName,
                       .implementor = "The Android Open Source Project"},
            .capability = Capability::make<Capability::bassBoost>(kCapability)};

    ndk::ScopedAStatus getParameterBassBoost(const BassBoost::Tag& tag,
                                             Parameter::Specific* specific);
};
+20 −11
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@

#include "DynamicsProcessingSw.h"

using aidl::android::hardware::audio::effect::Descriptor;
using aidl::android::hardware::audio::effect::DynamicsProcessingSw;
using aidl::android::hardware::audio::effect::IEffect;
using aidl::android::hardware::audio::effect::kDynamicsProcessingSwImplUUID;
@@ -47,23 +48,31 @@ extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
    }
}

extern "C" binder_exception_t destroyEffect(const std::shared_ptr<IEffect>& instanceSp) {
    if (!instanceSp) {
        return EX_NONE;
    }
    State state;
    ndk::ScopedAStatus status = instanceSp->getState(&state);
    if (!status.isOk() || State::INIT != state) {
        LOG(ERROR) << __func__ << " instance " << instanceSp.get()
                   << " in state: " << toString(state) << ", status: " << status.getDescription();
        return EX_ILLEGAL_STATE;
extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
    if (!in_impl_uuid || *in_impl_uuid != kDynamicsProcessingSwImplUUID) {
        LOG(ERROR) << __func__ << "uuid not supported";
        return EX_ILLEGAL_ARGUMENT;
    }
    LOG(DEBUG) << __func__ << " instance " << instanceSp.get() << " destroyed";
    *_aidl_return = DynamicsProcessingSw::kDescriptor;
    return EX_NONE;
}

namespace aidl::android::hardware::audio::effect {

const std::string DynamicsProcessingSw::kEffectName = "DynamicsProcessingSw";
const DynamicsProcessing::Capability DynamicsProcessingSw::kCapability;
const Descriptor DynamicsProcessingSw::kDescriptor = {
        .common = {.id = {.type = kDynamicsProcessingTypeUUID,
                          .uuid = kDynamicsProcessingSwImplUUID,
                          .proxy = std::nullopt},
                   .flags = {.type = Flags::Type::INSERT,
                             .insert = Flags::Insert::FIRST,
                             .volume = Flags::Volume::CTRL},
                   .name = DynamicsProcessingSw::kEffectName,
                   .implementor = "The Android Open Source Project"},
        .capability = Capability::make<Capability::dynamicsProcessing>(
                DynamicsProcessingSw::kCapability)};

ndk::ScopedAStatus DynamicsProcessingSw::getDescriptor(Descriptor* _aidl_return) {
    LOG(DEBUG) << __func__ << kDescriptor.toString();
    *_aidl_return = kDescriptor;
Loading