diff --git a/audio/aidl/default/EffectConfig.cpp b/audio/aidl/default/EffectConfig.cpp index 5a83fef99a..71d111bd06 100644 --- a/audio/aidl/default/EffectConfig.cpp +++ b/audio/aidl/default/EffectConfig.cpp @@ -14,12 +14,17 @@ * limitations under the License. */ +#include +#include #define LOG_TAG "AHAL_EffectConfig" #include +#include #include #include "effectFactory-impl/EffectConfig.h" +using aidl::android::media::audio::common::AudioSource; +using aidl::android::media::audio::common::AudioStreamType; using aidl::android::media::audio::common::AudioUuid; namespace aidl::android::hardware::audio::effect { @@ -55,14 +60,16 @@ EffectConfig::EffectConfig(const std::string& file) { // Parse pre processing chains for (auto& xmlPreprocess : getChildren(xmlConfig, "preprocess")) { for (auto& xmlStream : getChildren(xmlPreprocess, "stream")) { - registerFailure(parseStream(xmlStream)); + // AudioSource + registerFailure(parseProcessing(Processing::Type::source, xmlStream)); } } // Parse post processing chains for (auto& xmlPostprocess : getChildren(xmlConfig, "postprocess")) { for (auto& xmlStream : getChildren(xmlPostprocess, "stream")) { - registerFailure(parseStream(xmlStream)); + // AudioStreamType + registerFailure(parseProcessing(Processing::Type::streamType, xmlStream)); } } } @@ -140,21 +147,6 @@ bool EffectConfig::parseEffect(const tinyxml2::XMLElement& xml) { return true; } -bool EffectConfig::parseStream(const tinyxml2::XMLElement& xml) { - LOG(DEBUG) << __func__ << dump(xml); - const char* type = xml.Attribute("type"); - RETURN_VALUE_IF(!type, false, "noTypeInProcess"); - RETURN_VALUE_IF(0 != mProcessingMap.count(type), false, "duplicateType"); - - for (auto& apply : getChildren(xml, "apply")) { - const char* name = apply.get().Attribute("effect"); - RETURN_VALUE_IF(!name, false, "noEffectAttribute"); - mProcessingMap[type].push_back(name); - LOG(DEBUG) << __func__ << " " << type << " : " << name; - } - return true; -} - bool EffectConfig::parseLibraryUuid(const tinyxml2::XMLElement& xml, struct LibraryUuid& libraryUuid, bool isProxy) { // Retrieve library name only if not effectProxy element @@ -174,6 +166,80 @@ bool EffectConfig::parseLibraryUuid(const tinyxml2::XMLElement& xml, return true; } +std::optional EffectConfig::stringToProcessingType(Processing::Type::Tag typeTag, + const std::string& type) { + // see list of audio stream types in audio_stream_type_t: + // system/media/audio/include/system/audio_effects/audio_effects_conf.h + // AUDIO_STREAM_DEFAULT_TAG is not listed here because according to SYS_RESERVED_DEFAULT in + // AudioStreamType.aidl: "Value reserved for system use only. HALs must never return this value + // to the system or accept it from the system". + static const std::map sAudioStreamTypeTable = { + {AUDIO_STREAM_VOICE_CALL_TAG, AudioStreamType::VOICE_CALL}, + {AUDIO_STREAM_SYSTEM_TAG, AudioStreamType::SYSTEM}, + {AUDIO_STREAM_RING_TAG, AudioStreamType::RING}, + {AUDIO_STREAM_MUSIC_TAG, AudioStreamType::MUSIC}, + {AUDIO_STREAM_ALARM_TAG, AudioStreamType::ALARM}, + {AUDIO_STREAM_NOTIFICATION_TAG, AudioStreamType::NOTIFICATION}, + {AUDIO_STREAM_BLUETOOTH_SCO_TAG, AudioStreamType::BLUETOOTH_SCO}, + {AUDIO_STREAM_ENFORCED_AUDIBLE_TAG, AudioStreamType::ENFORCED_AUDIBLE}, + {AUDIO_STREAM_DTMF_TAG, AudioStreamType::DTMF}, + {AUDIO_STREAM_TTS_TAG, AudioStreamType::TTS}, + {AUDIO_STREAM_ASSISTANT_TAG, AudioStreamType::ASSISTANT}}; + + // see list of audio sources in audio_source_t: + // system/media/audio/include/system/audio_effects/audio_effects_conf.h + static const std::map sAudioSourceTable = { + {MIC_SRC_TAG, AudioSource::VOICE_CALL}, + {VOICE_UL_SRC_TAG, AudioSource::VOICE_CALL}, + {VOICE_DL_SRC_TAG, AudioSource::VOICE_CALL}, + {VOICE_CALL_SRC_TAG, AudioSource::VOICE_CALL}, + {CAMCORDER_SRC_TAG, AudioSource::VOICE_CALL}, + {VOICE_REC_SRC_TAG, AudioSource::VOICE_CALL}, + {VOICE_COMM_SRC_TAG, AudioSource::VOICE_CALL}, + {REMOTE_SUBMIX_SRC_TAG, AudioSource::VOICE_CALL}, + {UNPROCESSED_SRC_TAG, AudioSource::VOICE_CALL}, + {VOICE_PERFORMANCE_SRC_TAG, AudioSource::VOICE_CALL}}; + + if (typeTag == Processing::Type::streamType) { + auto typeIter = sAudioStreamTypeTable.find(type); + if (typeIter != sAudioStreamTypeTable.end()) { + return typeIter->second; + } + } else if (typeTag == Processing::Type::source) { + auto typeIter = sAudioSourceTable.find(type); + if (typeIter != sAudioSourceTable.end()) { + return typeIter->second; + } + } + + return std::nullopt; +} + +bool EffectConfig::parseProcessing(Processing::Type::Tag typeTag, const tinyxml2::XMLElement& xml) { + LOG(DEBUG) << __func__ << dump(xml); + const char* typeStr = xml.Attribute("type"); + auto aidlType = stringToProcessingType(typeTag, typeStr); + RETURN_VALUE_IF(!aidlType.has_value(), false, "illegalStreamType"); + RETURN_VALUE_IF(0 != mProcessingMap.count(aidlType.value()), false, "duplicateStreamType"); + + for (auto& apply : getChildren(xml, "apply")) { + const char* name = apply.get().Attribute("effect"); + if (mEffectsMap.find(name) == mEffectsMap.end()) { + LOG(ERROR) << __func__ << " effect " << name << " doesn't exist, skipping"; + continue; + } + RETURN_VALUE_IF(!name, false, "noEffectAttribute"); + mProcessingMap[aidlType.value()].emplace_back(mEffectsMap[name]); + LOG(WARNING) << __func__ << " " << typeStr << " : " << name; + } + return true; +} + +const std::map>& +EffectConfig::getProcessingMap() const { + return mProcessingMap; +} + bool EffectConfig::findUuid(const std::string& xmlEffectName, AudioUuid* uuid) { // Difference from EFFECT_TYPE_LIST_DEF, there could be multiple name mapping to same Effect Type #define EFFECT_XML_TYPE_LIST_DEF(V) \ diff --git a/audio/aidl/default/EffectFactory.cpp b/audio/aidl/default/EffectFactory.cpp index f0687cc80f..7073a10c96 100644 --- a/audio/aidl/default/EffectFactory.cpp +++ b/audio/aidl/default/EffectFactory.cpp @@ -15,8 +15,10 @@ */ #include +#include #include #include +#include #include #include #define LOG_TAG "AHAL_EffectFactory" @@ -52,6 +54,22 @@ Factory::~Factory() { } } +ndk::ScopedAStatus Factory::getDescriptorWithUuid(const AudioUuid& uuid, Descriptor* desc) { + RETURN_IF(!desc, EX_NULL_POINTER, "nullDescriptor"); + + if (mEffectLibMap.count(uuid)) { + auto& entry = mEffectLibMap[uuid]; + getDlSyms(entry); + auto& libInterface = std::get(entry); + RETURN_IF(!libInterface || !libInterface->queryEffectFunc, EX_NULL_POINTER, + "dlNullQueryEffectFunc"); + RETURN_IF_BINDER_EXCEPTION(libInterface->queryEffectFunc(&uuid, desc)); + return ndk::ScopedAStatus::ok(); + } + + return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); +} + ndk::ScopedAStatus Factory::queryEffects(const std::optional& in_type_uuid, const std::optional& in_impl_uuid, const std::optional& in_proxy_uuid, @@ -69,12 +87,7 @@ ndk::ScopedAStatus Factory::queryEffects(const std::optional& in_type for (const auto& id : idList) { if (mEffectLibMap.count(id.uuid)) { Descriptor desc; - auto& entry = mEffectLibMap[id.uuid]; - getDlSyms(entry); - auto& libInterface = std::get(entry); - RETURN_IF(!libInterface || !libInterface->queryEffectFunc, EX_NULL_POINTER, - "dlNullQueryEffectFunc"); - RETURN_IF_BINDER_EXCEPTION(libInterface->queryEffectFunc(&id.uuid, &desc)); + RETURN_IF_ASTATUS_NOT_OK(getDescriptorWithUuid(id.uuid, &desc), "getDescriptorFailed"); // update proxy UUID with information from config xml desc.common.id.proxy = id.proxy; _aidl_return->emplace_back(std::move(desc)); @@ -85,12 +98,26 @@ ndk::ScopedAStatus Factory::queryEffects(const std::optional& in_type ndk::ScopedAStatus Factory::queryProcessing(const std::optional& in_type, std::vector* _aidl_return) { - // TODO: implement this with audio_effect.xml. - if (in_type.has_value()) { - // return all matching process filter - LOG(DEBUG) << __func__ << " process type: " << in_type.value().toString(); + const auto& processings = mConfig.getProcessingMap(); + // Processing stream type + for (const auto& procIter : processings) { + if (!in_type.has_value() || in_type.value() == procIter.first) { + Processing process = {.type = procIter.first /* Processing::Type */}; + for (const auto& libs : procIter.second /* std::vector */) { + for (const auto& lib : libs.libraries /* std::vector */) { + Descriptor desc; + if (libs.proxyLibrary.has_value()) { + desc.common.id.proxy = libs.proxyLibrary.value().uuid; + } + RETURN_IF_ASTATUS_NOT_OK(getDescriptorWithUuid(lib.uuid, &desc), + "getDescriptorFailed"); + process.ids.emplace_back(desc); + } + } + _aidl_return->emplace_back(process); + } } - LOG(DEBUG) << __func__ << " return " << _aidl_return->size(); + return ndk::ScopedAStatus::ok(); } diff --git a/audio/aidl/default/audio_effects_config.xml b/audio/aidl/default/audio_effects_config.xml index c06742d966..6627ae7533 100644 --- a/audio/aidl/default/audio_effects_config.xml +++ b/audio/aidl/default/audio_effects_config.xml @@ -95,8 +95,17 @@ + + + + + + + + +