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

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

Merge changes I415a7be5,Id3ec0934 am: aa519f35 am: a9ec329d

parents f5ce2611 a9ec329d
Loading
Loading
Loading
Loading
+7 −6
Original line number Diff line number Diff line
@@ -49,26 +49,27 @@ struct Library {
    std::string name;
    std::string path;
};
using Libraries = std::vector<Library>;
using Libraries = std::vector<std::shared_ptr<const Library>>;

struct EffectImpl {
    Library* library; //< Only valid as long as the associated library vector is unmodified
    //< Only valid as long as the associated library vector is unmodified
    std::shared_ptr<const Library> library;
    effect_uuid_t uuid;
};

struct Effect : public EffectImpl {
    std::string name;
    bool isProxy;
    EffectImpl libSw; //< Only valid if isProxy
    EffectImpl libHw; //< Only valid if isProxy
    std::shared_ptr<EffectImpl> libSw; //< Only valid if isProxy
    std::shared_ptr<EffectImpl> libHw; //< Only valid if isProxy
};

using Effects = std::vector<Effect>;
using Effects = std::vector<std::shared_ptr<const Effect>>;

template <class Type>
struct Stream {
    Type type;
    std::vector<std::reference_wrapper<Effect>> effects;
    Effects effects;
};
using OutputStream = Stream<audio_stream_type_t>;
using InputStream = Stream<audio_source_t>;
+19 −10
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
#include <algorithm>
#include <cstdint>
#include <functional>
#include <memory>
#include <string>
#include <unistd.h>

@@ -149,7 +150,10 @@ bool parseLibrary(const XMLElement& xmlLibrary, Libraries* libraries) {
        ALOGE("library must have a name and a path: %s", dump(xmlLibrary));
        return false;
    }
    libraries->push_back({name, path});

    // need this temp variable because `struct Library` doesn't have a constructor
    Library lib({.name = name, .path = path});
    libraries->push_back(std::make_shared<const Library>(lib));
    return true;
}

@@ -157,10 +161,10 @@ bool parseLibrary(const XMLElement& xmlLibrary, Libraries* libraries) {
 * @return nullptr if not found, the element address if found.
 */
template <class T>
T* findByName(const char* name, std::vector<T>& collection) {
T findByName(const char* name, std::vector<T>& collection) {
    auto it = find_if(begin(collection), end(collection),
                         [name] (auto& item) { return item.name == name; });
    return it != end(collection) ? &*it : nullptr;
                      [name](auto& item) { return item && item->name == name; });
    return it != end(collection) ? *it : nullptr;
}

/** Parse an effect from an xml element describing it.
@@ -187,7 +191,7 @@ bool parseEffect(const XMLElement& xmlEffect, Libraries& libraries, Effects* eff
        }

        // Convert library name to a pointer to the previously loaded library
        auto* library = findByName(libraryName, libraries);
        auto library = findByName(libraryName, libraries);
        if (library == nullptr) {
            ALOGE("Could not find library referenced in: %s", dump(xmlImpl));
            return false;
@@ -211,20 +215,25 @@ bool parseEffect(const XMLElement& xmlEffect, Libraries& libraries, Effects* eff
        effect.isProxy = true;

        // Function to parse libhw and libsw
        auto parseProxy = [&xmlEffect, &parseImpl](const char* tag, EffectImpl& proxyLib) {
        auto parseProxy = [&xmlEffect, &parseImpl](const char* tag,
                                                   const std::shared_ptr<EffectImpl>& proxyLib) {
            auto* xmlProxyLib = xmlEffect.FirstChildElement(tag);
            if (xmlProxyLib == nullptr) {
                ALOGE("effectProxy must contain a <%s>: %s", tag, dump(xmlEffect));
                return false;
            }
            return parseImpl(*xmlProxyLib, proxyLib);
            return parseImpl(*xmlProxyLib, *proxyLib);
        };
        effect.libSw = std::make_shared<EffectImpl>();
        effect.libHw = std::make_shared<EffectImpl>();
        if (!parseProxy("libhw", effect.libHw) || !parseProxy("libsw", effect.libSw)) {
            effect.libSw.reset();
            effect.libHw.reset();
            return false;
        }
    }

    effects->push_back(std::move(effect));
    effects->push_back(std::make_shared<const Effect>(effect));
    return true;
}

@@ -250,12 +259,12 @@ bool parseStream(const XMLElement& xmlStream, Effects& effects, std::vector<Stre
            ALOGE("<stream|device>/apply must have reference an effect: %s", dump(xmlApply));
            return false;
        }
        auto* effect = findByName(effectName, effects);
        auto effect = findByName(effectName, effects);
        if (effect == nullptr) {
            ALOGE("Could not find effect referenced in: %s", dump(xmlApply));
            return false;
        }
        stream.effects.emplace_back(*effect);
        stream.effects.emplace_back(effect);
    }
    streams->push_back(std::move(stream));
    return true;
+29 −26
Original line number Diff line number Diff line
@@ -63,7 +63,7 @@ bool loadLibrary(const char* relativePath, lib_entry_t* libEntry) noexcept {

    std::string absolutePath;
    if (!resolveLibrary(relativePath, &absolutePath)) {
        ALOGE("Could not find library in effect directories: %s", relativePath);
        ALOGE("%s Could not find library in effect directories: %s", __func__, relativePath);
        libEntry->path = strdup(relativePath);
        return false;
    }
@@ -74,20 +74,20 @@ bool loadLibrary(const char* relativePath, lib_entry_t* libEntry) noexcept {
    std::unique_ptr<void, decltype(dlclose)*> libHandle(dlopen(path, RTLD_NOW),
                                                       dlclose);
    if (libHandle == nullptr) {
        ALOGE("Could not dlopen library %s: %s", path, dlerror());
        ALOGE("%s Could not dlopen library %s: %s", __func__, path, dlerror());
        return false;
    }

    auto* description = static_cast<audio_effect_library_t*>(
          dlsym(libHandle.get(), AUDIO_EFFECT_LIBRARY_INFO_SYM_AS_STR));
    if (description == nullptr) {
        ALOGE("Invalid effect library, failed not find symbol '%s' in %s: %s",
        ALOGE("%s Invalid effect library, failed not find symbol '%s' in %s: %s", __func__,
              AUDIO_EFFECT_LIBRARY_INFO_SYM_AS_STR, path, dlerror());
        return false;
    }

    if (description->tag != AUDIO_EFFECT_LIBRARY_TAG) {
        ALOGE("Bad tag %#08x in description structure, expected %#08x for library %s",
        ALOGE("%s Bad tag %#08x in description structure, expected %#08x for library %s", __func__,
              description->tag, AUDIO_EFFECT_LIBRARY_TAG, path);
        return false;
    }
@@ -95,8 +95,8 @@ bool loadLibrary(const char* relativePath, lib_entry_t* libEntry) noexcept {
    uint32_t majorVersion = EFFECT_API_VERSION_MAJOR(description->version);
    uint32_t expectedMajorVersion = EFFECT_API_VERSION_MAJOR(EFFECT_LIBRARY_API_VERSION_CURRENT);
    if (majorVersion != expectedMajorVersion) {
        ALOGE("Unsupported major version %#08x, expected %#08x for library %s",
              majorVersion, expectedMajorVersion, path);
        ALOGE("%s Unsupported major version %#08x, expected %#08x for library %s",
              __func__, majorVersion, expectedMajorVersion, path);
        return false;
    }

@@ -154,14 +154,13 @@ size_t loadLibraries(const effectsConfig::Libraries& libs,
{
    size_t nbSkippedElement = 0;
    for (auto& library : libs) {

        // Construct a lib entry
        auto libEntry = makeUniqueC<lib_entry_t>();
        libEntry->name = strdup(library.name.c_str());
        libEntry->name = strdup(library->name.c_str());
        libEntry->effects = nullptr;
        pthread_mutex_init(&libEntry->lock, nullptr);

        if (!loadLibrary(library.path.c_str(), libEntry.get())) {
        if (!loadLibrary(library->path.c_str(), libEntry.get())) {
            // Register library load failure
            listPush(std::move(libEntry), libFailedList);
            ++nbSkippedElement;
@@ -208,24 +207,24 @@ struct LoadEffectResult {
    UniqueCPtr<effect_descriptor_t> effectDesc;
};

LoadEffectResult loadEffect(const EffectImpl& effect, const std::string& name,
                            list_elem_t* libList) {
LoadEffectResult loadEffect(const std::shared_ptr<const EffectImpl>& effect,
                            const std::string& name, list_elem_t* libList) {
    LoadEffectResult result;

    // Find the effect library
    result.lib = findLibrary(effect.library->name.c_str(), libList);
    result.lib = findLibrary(effect->library->name.c_str(), libList);
    if (result.lib == nullptr) {
        ALOGE("Could not find library %s to load effect %s",
              effect.library->name.c_str(), name.c_str());
        ALOGE("%s Could not find library %s to load effect %s",
              __func__, effect->library->name.c_str(), name.c_str());
        return result;
    }

    result.effectDesc = makeUniqueC<effect_descriptor_t>();

    // Get the effect descriptor
    if (result.lib->desc->get_descriptor(&effect.uuid, result.effectDesc.get()) != 0) {
    if (result.lib->desc->get_descriptor(&effect->uuid, result.effectDesc.get()) != 0) {
        ALOGE("Error querying effect %s on lib %s",
              uuidToString(effect.uuid), result.lib->name);
              uuidToString(effect->uuid), result.lib->name);
        result.effectDesc.reset();
        return result;
    }
@@ -240,14 +239,15 @@ LoadEffectResult loadEffect(const EffectImpl& effect, const std::string& name,
    // Check effect is supported
    uint32_t expectedMajorVersion = EFFECT_API_VERSION_MAJOR(EFFECT_CONTROL_API_VERSION);
    if (EFFECT_API_VERSION_MAJOR(result.effectDesc->apiVersion) != expectedMajorVersion) {
        ALOGE("Bad API version %#08x for effect %s in lib %s, expected major %#08x",
        ALOGE("%s Bad API version %#08x for effect %s in lib %s, expected major %#08x", __func__,
              result.effectDesc->apiVersion, name.c_str(), result.lib->name, expectedMajorVersion);
        return result;
    }

    lib_entry_t *_;
    if (findEffect(nullptr, &effect.uuid, &_, nullptr) == 0) {
        ALOGE("Effect %s uuid %s already exist", uuidToString(effect.uuid), name.c_str());
    if (findEffect(nullptr, &effect->uuid, &_, nullptr) == 0) {
        ALOGE("%s Effect %s uuid %s already exist", __func__, uuidToString(effect->uuid),
              name.c_str());
        return result;
    }

@@ -260,8 +260,11 @@ size_t loadEffects(const Effects& effects, list_elem_t* libList, list_elem_t** s
    size_t nbSkippedElement = 0;

    for (auto& effect : effects) {
        if (!effect) {
            continue;
        }

        auto effectLoadResult = loadEffect(effect, effect.name, libList);
        auto effectLoadResult = loadEffect(effect, effect->name, libList);
        if (!effectLoadResult.success) {
            if (effectLoadResult.effectDesc != nullptr) {
                listPush(std::move(effectLoadResult.effectDesc), skippedEffects);
@@ -270,9 +273,9 @@ size_t loadEffects(const Effects& effects, list_elem_t* libList, list_elem_t** s
            continue;
        }

        if (effect.isProxy) {
            auto swEffectLoadResult = loadEffect(effect.libSw, effect.name + " libsw", libList);
            auto hwEffectLoadResult = loadEffect(effect.libHw, effect.name + " libhw", libList);
        if (effect->isProxy) {
            auto swEffectLoadResult = loadEffect(effect->libSw, effect->name + " libsw", libList);
            auto hwEffectLoadResult = loadEffect(effect->libHw, effect->name + " libhw", libList);
            if (!swEffectLoadResult.success || !hwEffectLoadResult.success) {
                // Push the main effect in the skipped list even if only a subeffect is invalid
                // as the main effect is not usable without its subeffects.
@@ -286,7 +289,7 @@ size_t loadEffects(const Effects& effects, list_elem_t* libList, list_elem_t** s
            // get_descriptor call, we replace it with the corresponding
            // sw effect descriptor, but keep the Proxy UUID
            *effectLoadResult.effectDesc = *swEffectLoadResult.effectDesc;
            effectLoadResult.effectDesc->uuid = effect.uuid;
            effectLoadResult.effectDesc->uuid = effect->uuid;

            effectLoadResult.effectDesc->flags |= EFFECT_FLAG_OFFLOAD_SUPPORTED;

@@ -325,8 +328,8 @@ extern "C" ssize_t EffectLoadXmlEffectConfig(const char* path)
                               loadEffects(result.parsedConfig->effects, gLibraryList,
                                           &gSkippedEffects, &gSubEffectList);

    ALOGE_IF(result.nbSkippedElement != 0, "%zu errors during loading of configuration: %s",
             result.nbSkippedElement,
    ALOGE_IF(result.nbSkippedElement != 0, "%s %zu errors during loading of configuration: %s",
             __func__, result.nbSkippedElement,
             result.configPath.empty() ? "No config file found" : result.configPath.c_str());

    return result.nbSkippedElement;
+2 −4
Original line number Diff line number Diff line
@@ -918,8 +918,7 @@ status_t AudioPolicyEffects::loadAudioEffectConfig(
        for (auto& stream : processingChain) {
            auto effectDescs = std::make_unique<EffectDescVector>();
            for (auto& effect : stream.effects) {
                effectDescs->mEffects.add(
                        new EffectDesc{effect.get().name.c_str(), effect.get().uuid});
                effectDescs->mEffects.add(new EffectDesc{effect->name.c_str(), effect->uuid});
            }
            streams.add(stream.type, effectDescs.release());
        }
@@ -929,8 +928,7 @@ status_t AudioPolicyEffects::loadAudioEffectConfig(
        for (auto& deviceProcess : processingChain) {
            auto effectDescs = std::make_unique<EffectDescVector>();
            for (auto& effect : deviceProcess.effects) {
                effectDescs->mEffects.add(
                        new EffectDesc{effect.get().name.c_str(), effect.get().uuid});
                effectDescs->mEffects.add(new EffectDesc{effect->name.c_str(), effect->uuid});
            }
            auto deviceEffects = std::make_unique<DeviceEffects>(
                        std::move(effectDescs), deviceProcess.type, deviceProcess.address);