xref: /aosp_15_r20/hardware/interfaces/audio/aidl/default/EffectConfig.cpp (revision 4d7e907c777eeecc4c5bd7cf640a754fac206ff7)
1*4d7e907cSAndroid Build Coastguard Worker /*
2*4d7e907cSAndroid Build Coastguard Worker  * Copyright (C) 2022 The Android Open Source Project
3*4d7e907cSAndroid Build Coastguard Worker  *
4*4d7e907cSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*4d7e907cSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*4d7e907cSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*4d7e907cSAndroid Build Coastguard Worker  *
8*4d7e907cSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*4d7e907cSAndroid Build Coastguard Worker  *
10*4d7e907cSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*4d7e907cSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*4d7e907cSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*4d7e907cSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*4d7e907cSAndroid Build Coastguard Worker  * limitations under the License.
15*4d7e907cSAndroid Build Coastguard Worker  */
16*4d7e907cSAndroid Build Coastguard Worker 
17*4d7e907cSAndroid Build Coastguard Worker #include <optional>
18*4d7e907cSAndroid Build Coastguard Worker #include <string>
19*4d7e907cSAndroid Build Coastguard Worker #define LOG_TAG "AHAL_EffectConfig"
20*4d7e907cSAndroid Build Coastguard Worker #include <android-base/logging.h>
21*4d7e907cSAndroid Build Coastguard Worker #include <media/AidlConversionCppNdk.h>
22*4d7e907cSAndroid Build Coastguard Worker #include <system/audio.h>
23*4d7e907cSAndroid Build Coastguard Worker #include <system/audio_aidl_utils.h>
24*4d7e907cSAndroid Build Coastguard Worker #include <system/audio_effects/audio_effects_conf.h>
25*4d7e907cSAndroid Build Coastguard Worker #include <system/audio_effects/effect_uuid.h>
26*4d7e907cSAndroid Build Coastguard Worker 
27*4d7e907cSAndroid Build Coastguard Worker #include "effectFactory-impl/EffectConfig.h"
28*4d7e907cSAndroid Build Coastguard Worker 
29*4d7e907cSAndroid Build Coastguard Worker #ifdef __ANDROID_APEX__
30*4d7e907cSAndroid Build Coastguard Worker #include <android/apexsupport.h>
31*4d7e907cSAndroid Build Coastguard Worker #endif
32*4d7e907cSAndroid Build Coastguard Worker 
33*4d7e907cSAndroid Build Coastguard Worker using aidl::android::media::audio::common::AudioDevice;
34*4d7e907cSAndroid Build Coastguard Worker using aidl::android::media::audio::common::AudioDeviceAddress;
35*4d7e907cSAndroid Build Coastguard Worker using aidl::android::media::audio::common::AudioDeviceDescription;
36*4d7e907cSAndroid Build Coastguard Worker using aidl::android::media::audio::common::AudioDeviceType;
37*4d7e907cSAndroid Build Coastguard Worker using aidl::android::media::audio::common::AudioSource;
38*4d7e907cSAndroid Build Coastguard Worker using aidl::android::media::audio::common::AudioStreamType;
39*4d7e907cSAndroid Build Coastguard Worker using aidl::android::media::audio::common::AudioUuid;
40*4d7e907cSAndroid Build Coastguard Worker 
41*4d7e907cSAndroid Build Coastguard Worker namespace aidl::android::hardware::audio::effect {
42*4d7e907cSAndroid Build Coastguard Worker 
EffectConfig(const std::string & file)43*4d7e907cSAndroid Build Coastguard Worker EffectConfig::EffectConfig(const std::string& file) {
44*4d7e907cSAndroid Build Coastguard Worker     tinyxml2::XMLDocument doc;
45*4d7e907cSAndroid Build Coastguard Worker     doc.LoadFile(file.c_str());
46*4d7e907cSAndroid Build Coastguard Worker     // parse the xml file into maps
47*4d7e907cSAndroid Build Coastguard Worker     if (doc.Error()) {
48*4d7e907cSAndroid Build Coastguard Worker         LOG(ERROR) << __func__ << " tinyxml2 failed to load " << file
49*4d7e907cSAndroid Build Coastguard Worker                    << " error: " << doc.ErrorStr();
50*4d7e907cSAndroid Build Coastguard Worker         return;
51*4d7e907cSAndroid Build Coastguard Worker     }
52*4d7e907cSAndroid Build Coastguard Worker 
53*4d7e907cSAndroid Build Coastguard Worker     auto registerFailure = [&](bool result) { mSkippedElements += result ? 0 : 1; };
54*4d7e907cSAndroid Build Coastguard Worker 
55*4d7e907cSAndroid Build Coastguard Worker     for (auto& xmlConfig : getChildren(doc, "audio_effects_conf")) {
56*4d7e907cSAndroid Build Coastguard Worker         // Parse library
57*4d7e907cSAndroid Build Coastguard Worker         for (auto& xmlLibraries : getChildren(xmlConfig, "libraries")) {
58*4d7e907cSAndroid Build Coastguard Worker             for (auto& xmlLibrary : getChildren(xmlLibraries, "library")) {
59*4d7e907cSAndroid Build Coastguard Worker                 registerFailure(parseLibrary(xmlLibrary));
60*4d7e907cSAndroid Build Coastguard Worker             }
61*4d7e907cSAndroid Build Coastguard Worker         }
62*4d7e907cSAndroid Build Coastguard Worker 
63*4d7e907cSAndroid Build Coastguard Worker         // Parse effects
64*4d7e907cSAndroid Build Coastguard Worker         for (auto& xmlEffects : getChildren(xmlConfig, "effects")) {
65*4d7e907cSAndroid Build Coastguard Worker             for (auto& xmlEffect : getChildren(xmlEffects)) {
66*4d7e907cSAndroid Build Coastguard Worker                 registerFailure(parseEffect(xmlEffect));
67*4d7e907cSAndroid Build Coastguard Worker             }
68*4d7e907cSAndroid Build Coastguard Worker         }
69*4d7e907cSAndroid Build Coastguard Worker 
70*4d7e907cSAndroid Build Coastguard Worker         // Parse pre processing chains
71*4d7e907cSAndroid Build Coastguard Worker         for (auto& xmlPreprocess : getChildren(xmlConfig, "preprocess")) {
72*4d7e907cSAndroid Build Coastguard Worker             for (auto& xmlStream : getChildren(xmlPreprocess, "stream")) {
73*4d7e907cSAndroid Build Coastguard Worker                 // AudioSource
74*4d7e907cSAndroid Build Coastguard Worker                 registerFailure(parseProcessing(Processing::Type::source, xmlStream));
75*4d7e907cSAndroid Build Coastguard Worker             }
76*4d7e907cSAndroid Build Coastguard Worker         }
77*4d7e907cSAndroid Build Coastguard Worker 
78*4d7e907cSAndroid Build Coastguard Worker         // Parse post processing chains
79*4d7e907cSAndroid Build Coastguard Worker         for (auto& xmlPostprocess : getChildren(xmlConfig, "postprocess")) {
80*4d7e907cSAndroid Build Coastguard Worker             for (auto& xmlStream : getChildren(xmlPostprocess, "stream")) {
81*4d7e907cSAndroid Build Coastguard Worker                 // AudioStreamType
82*4d7e907cSAndroid Build Coastguard Worker                 registerFailure(parseProcessing(Processing::Type::streamType, xmlStream));
83*4d7e907cSAndroid Build Coastguard Worker             }
84*4d7e907cSAndroid Build Coastguard Worker         }
85*4d7e907cSAndroid Build Coastguard Worker 
86*4d7e907cSAndroid Build Coastguard Worker         // Parse device effect chains
87*4d7e907cSAndroid Build Coastguard Worker         for (auto& xmlDeviceEffects : getChildren(xmlConfig, "deviceEffects")) {
88*4d7e907cSAndroid Build Coastguard Worker             for (auto& xmlDevice : getChildren(xmlDeviceEffects, "device")) {
89*4d7e907cSAndroid Build Coastguard Worker                 // AudioDevice
90*4d7e907cSAndroid Build Coastguard Worker                 registerFailure(parseProcessing(Processing::Type::device, xmlDevice));
91*4d7e907cSAndroid Build Coastguard Worker             }
92*4d7e907cSAndroid Build Coastguard Worker         }
93*4d7e907cSAndroid Build Coastguard Worker     }
94*4d7e907cSAndroid Build Coastguard Worker     LOG(DEBUG) << __func__ << " successfully parsed " << file << ", skipping " << mSkippedElements
95*4d7e907cSAndroid Build Coastguard Worker                << " element(s)";
96*4d7e907cSAndroid Build Coastguard Worker }
97*4d7e907cSAndroid Build Coastguard Worker 
getChildren(const tinyxml2::XMLNode & node,const char * childTag)98*4d7e907cSAndroid Build Coastguard Worker std::vector<std::reference_wrapper<const tinyxml2::XMLElement>> EffectConfig::getChildren(
99*4d7e907cSAndroid Build Coastguard Worker         const tinyxml2::XMLNode& node, const char* childTag) {
100*4d7e907cSAndroid Build Coastguard Worker     std::vector<std::reference_wrapper<const tinyxml2::XMLElement>> children;
101*4d7e907cSAndroid Build Coastguard Worker     for (auto* child = node.FirstChildElement(childTag); child != nullptr;
102*4d7e907cSAndroid Build Coastguard Worker          child = child->NextSiblingElement(childTag)) {
103*4d7e907cSAndroid Build Coastguard Worker         children.emplace_back(*child);
104*4d7e907cSAndroid Build Coastguard Worker     }
105*4d7e907cSAndroid Build Coastguard Worker     return children;
106*4d7e907cSAndroid Build Coastguard Worker }
107*4d7e907cSAndroid Build Coastguard Worker 
resolveLibrary(const std::string & path,std::string * resolvedPath)108*4d7e907cSAndroid Build Coastguard Worker bool EffectConfig::resolveLibrary(const std::string& path, std::string* resolvedPath) {
109*4d7e907cSAndroid Build Coastguard Worker     if constexpr (__ANDROID_VENDOR_API__ >= 202404) {
110*4d7e907cSAndroid Build Coastguard Worker         AApexInfo *apexInfo;
111*4d7e907cSAndroid Build Coastguard Worker         if (AApexInfo_create(&apexInfo) == AAPEXINFO_OK) {
112*4d7e907cSAndroid Build Coastguard Worker             std::string apexName(AApexInfo_getName(apexInfo));
113*4d7e907cSAndroid Build Coastguard Worker             AApexInfo_destroy(apexInfo);
114*4d7e907cSAndroid Build Coastguard Worker             std::string candidatePath("/apex/");
115*4d7e907cSAndroid Build Coastguard Worker             candidatePath.append(apexName).append(kEffectLibApexPath).append(path);
116*4d7e907cSAndroid Build Coastguard Worker             LOG(DEBUG) << __func__ << " effect lib path " << candidatePath;
117*4d7e907cSAndroid Build Coastguard Worker             if (access(candidatePath.c_str(), R_OK) == 0) {
118*4d7e907cSAndroid Build Coastguard Worker                 *resolvedPath = std::move(candidatePath);
119*4d7e907cSAndroid Build Coastguard Worker                 return true;
120*4d7e907cSAndroid Build Coastguard Worker             }
121*4d7e907cSAndroid Build Coastguard Worker         }
122*4d7e907cSAndroid Build Coastguard Worker     } else {
123*4d7e907cSAndroid Build Coastguard Worker         LOG(DEBUG) << __func__ << " libapexsupport is not supported";
124*4d7e907cSAndroid Build Coastguard Worker     }
125*4d7e907cSAndroid Build Coastguard Worker 
126*4d7e907cSAndroid Build Coastguard Worker     // If audio effects libs are not in vendor apex, locate them in kEffectLibPath
127*4d7e907cSAndroid Build Coastguard Worker     for (auto* libraryDirectory : kEffectLibPath) {
128*4d7e907cSAndroid Build Coastguard Worker         std::string candidatePath = std::string(libraryDirectory) + '/' + path;
129*4d7e907cSAndroid Build Coastguard Worker         if (access(candidatePath.c_str(), R_OK) == 0) {
130*4d7e907cSAndroid Build Coastguard Worker             *resolvedPath = std::move(candidatePath);
131*4d7e907cSAndroid Build Coastguard Worker             return true;
132*4d7e907cSAndroid Build Coastguard Worker         }
133*4d7e907cSAndroid Build Coastguard Worker     }
134*4d7e907cSAndroid Build Coastguard Worker     return false;
135*4d7e907cSAndroid Build Coastguard Worker }
136*4d7e907cSAndroid Build Coastguard Worker 
parseLibrary(const tinyxml2::XMLElement & xml)137*4d7e907cSAndroid Build Coastguard Worker bool EffectConfig::parseLibrary(const tinyxml2::XMLElement& xml) {
138*4d7e907cSAndroid Build Coastguard Worker     const char* name = xml.Attribute("name");
139*4d7e907cSAndroid Build Coastguard Worker     RETURN_VALUE_IF(!name, false, "noNameAttribute");
140*4d7e907cSAndroid Build Coastguard Worker     const char* path = xml.Attribute("path");
141*4d7e907cSAndroid Build Coastguard Worker     RETURN_VALUE_IF(!path, false, "noPathAttribute");
142*4d7e907cSAndroid Build Coastguard Worker 
143*4d7e907cSAndroid Build Coastguard Worker     std::string resolvedPath;
144*4d7e907cSAndroid Build Coastguard Worker     if (!resolveLibrary(path, &resolvedPath)) {
145*4d7e907cSAndroid Build Coastguard Worker         LOG(ERROR) << __func__ << " can't find " << path;
146*4d7e907cSAndroid Build Coastguard Worker         return false;
147*4d7e907cSAndroid Build Coastguard Worker     }
148*4d7e907cSAndroid Build Coastguard Worker     mLibraryMap[name] = resolvedPath;
149*4d7e907cSAndroid Build Coastguard Worker     LOG(DEBUG) << __func__ << " " << name << " : " << resolvedPath;
150*4d7e907cSAndroid Build Coastguard Worker     return true;
151*4d7e907cSAndroid Build Coastguard Worker }
152*4d7e907cSAndroid Build Coastguard Worker 
parseEffect(const tinyxml2::XMLElement & xml)153*4d7e907cSAndroid Build Coastguard Worker bool EffectConfig::parseEffect(const tinyxml2::XMLElement& xml) {
154*4d7e907cSAndroid Build Coastguard Worker     struct EffectLibraries effectLibraries;
155*4d7e907cSAndroid Build Coastguard Worker     std::vector<Library> libraries;
156*4d7e907cSAndroid Build Coastguard Worker     std::string name = xml.Attribute("name");
157*4d7e907cSAndroid Build Coastguard Worker     RETURN_VALUE_IF(name == "", false, "effectsNoName");
158*4d7e907cSAndroid Build Coastguard Worker 
159*4d7e907cSAndroid Build Coastguard Worker     LOG(VERBOSE) << __func__ << dump(xml);
160*4d7e907cSAndroid Build Coastguard Worker     struct Library library;
161*4d7e907cSAndroid Build Coastguard Worker     if (std::strcmp(xml.Name(), "effectProxy") == 0) {
162*4d7e907cSAndroid Build Coastguard Worker         // proxy lib and uuid
163*4d7e907cSAndroid Build Coastguard Worker         RETURN_VALUE_IF(!parseLibrary(xml, library, true), false, "parseProxyLibFailed");
164*4d7e907cSAndroid Build Coastguard Worker         effectLibraries.proxyLibrary = library;
165*4d7e907cSAndroid Build Coastguard Worker         // proxy effect libs and UUID
166*4d7e907cSAndroid Build Coastguard Worker         auto xmlProxyLib = xml.FirstChildElement();
167*4d7e907cSAndroid Build Coastguard Worker         RETURN_VALUE_IF(!xmlProxyLib, false, "noLibForProxy");
168*4d7e907cSAndroid Build Coastguard Worker         while (xmlProxyLib) {
169*4d7e907cSAndroid Build Coastguard Worker             struct Library tempLibrary;
170*4d7e907cSAndroid Build Coastguard Worker             RETURN_VALUE_IF(!parseLibrary(*xmlProxyLib, tempLibrary), false,
171*4d7e907cSAndroid Build Coastguard Worker                             "parseEffectLibFailed");
172*4d7e907cSAndroid Build Coastguard Worker             libraries.push_back(std::move(tempLibrary));
173*4d7e907cSAndroid Build Coastguard Worker             xmlProxyLib = xmlProxyLib->NextSiblingElement();
174*4d7e907cSAndroid Build Coastguard Worker         }
175*4d7e907cSAndroid Build Coastguard Worker     } else {
176*4d7e907cSAndroid Build Coastguard Worker         // expect only one library if not proxy
177*4d7e907cSAndroid Build Coastguard Worker         RETURN_VALUE_IF(!parseLibrary(xml, library), false, "parseEffectLibFailed");
178*4d7e907cSAndroid Build Coastguard Worker         libraries.push_back(std::move(library));
179*4d7e907cSAndroid Build Coastguard Worker     }
180*4d7e907cSAndroid Build Coastguard Worker 
181*4d7e907cSAndroid Build Coastguard Worker     effectLibraries.libraries = std::move(libraries);
182*4d7e907cSAndroid Build Coastguard Worker     mEffectsMap[name] = std::move(effectLibraries);
183*4d7e907cSAndroid Build Coastguard Worker     return true;
184*4d7e907cSAndroid Build Coastguard Worker }
185*4d7e907cSAndroid Build Coastguard Worker 
parseLibrary(const tinyxml2::XMLElement & xml,struct Library & library,bool isProxy)186*4d7e907cSAndroid Build Coastguard Worker bool EffectConfig::parseLibrary(const tinyxml2::XMLElement& xml, struct Library& library,
187*4d7e907cSAndroid Build Coastguard Worker                                 bool isProxy) {
188*4d7e907cSAndroid Build Coastguard Worker     // Retrieve library name only if not effectProxy element
189*4d7e907cSAndroid Build Coastguard Worker     if (!isProxy) {
190*4d7e907cSAndroid Build Coastguard Worker         const char* name = xml.Attribute("library");
191*4d7e907cSAndroid Build Coastguard Worker         RETURN_VALUE_IF(!name, false, "noLibraryAttribute");
192*4d7e907cSAndroid Build Coastguard Worker         library.name = name;
193*4d7e907cSAndroid Build Coastguard Worker     }
194*4d7e907cSAndroid Build Coastguard Worker 
195*4d7e907cSAndroid Build Coastguard Worker     const char* uuidStr = xml.Attribute("uuid");
196*4d7e907cSAndroid Build Coastguard Worker     RETURN_VALUE_IF(!uuidStr, false, "noUuidAttribute");
197*4d7e907cSAndroid Build Coastguard Worker     library.uuid = stringToUuid(uuidStr);
198*4d7e907cSAndroid Build Coastguard Worker     if (const char* typeUuidStr = xml.Attribute("type")) {
199*4d7e907cSAndroid Build Coastguard Worker         library.type = stringToUuid(typeUuidStr);
200*4d7e907cSAndroid Build Coastguard Worker     }
201*4d7e907cSAndroid Build Coastguard Worker     RETURN_VALUE_IF((library.uuid == getEffectUuidZero()), false, "invalidUuidAttribute");
202*4d7e907cSAndroid Build Coastguard Worker 
203*4d7e907cSAndroid Build Coastguard Worker     LOG(VERBOSE) << __func__ << (isProxy ? " proxy " : library.name) << " : uuid "
204*4d7e907cSAndroid Build Coastguard Worker                  << ::android::audio::utils::toString(library.uuid)
205*4d7e907cSAndroid Build Coastguard Worker                  << (library.type.has_value()
206*4d7e907cSAndroid Build Coastguard Worker                              ? ::android::audio::utils::toString(library.type.value())
207*4d7e907cSAndroid Build Coastguard Worker                              : "");
208*4d7e907cSAndroid Build Coastguard Worker     return true;
209*4d7e907cSAndroid Build Coastguard Worker }
210*4d7e907cSAndroid Build Coastguard Worker 
stringToProcessingType(Processing::Type::Tag typeTag,const std::string & type,const std::string & address)211*4d7e907cSAndroid Build Coastguard Worker std::optional<Processing::Type> EffectConfig::stringToProcessingType(Processing::Type::Tag typeTag,
212*4d7e907cSAndroid Build Coastguard Worker                                                                      const std::string& type,
213*4d7e907cSAndroid Build Coastguard Worker                                                                      const std::string& address) {
214*4d7e907cSAndroid Build Coastguard Worker     // see list of audio stream types in audio_stream_type_t:
215*4d7e907cSAndroid Build Coastguard Worker     // system/media/audio/include/system/audio_effects/audio_effects_conf.h
216*4d7e907cSAndroid Build Coastguard Worker     // AUDIO_STREAM_DEFAULT_TAG is not listed here because according to SYS_RESERVED_DEFAULT in
217*4d7e907cSAndroid Build Coastguard Worker     // AudioStreamType.aidl: "Value reserved for system use only. HALs must never return this value
218*4d7e907cSAndroid Build Coastguard Worker     // to the system or accept it from the system".
219*4d7e907cSAndroid Build Coastguard Worker     static const std::map<const std::string, AudioStreamType> sAudioStreamTypeTable = {
220*4d7e907cSAndroid Build Coastguard Worker             {AUDIO_STREAM_VOICE_CALL_TAG, AudioStreamType::VOICE_CALL},
221*4d7e907cSAndroid Build Coastguard Worker             {AUDIO_STREAM_SYSTEM_TAG, AudioStreamType::SYSTEM},
222*4d7e907cSAndroid Build Coastguard Worker             {AUDIO_STREAM_RING_TAG, AudioStreamType::RING},
223*4d7e907cSAndroid Build Coastguard Worker             {AUDIO_STREAM_MUSIC_TAG, AudioStreamType::MUSIC},
224*4d7e907cSAndroid Build Coastguard Worker             {AUDIO_STREAM_ALARM_TAG, AudioStreamType::ALARM},
225*4d7e907cSAndroid Build Coastguard Worker             {AUDIO_STREAM_NOTIFICATION_TAG, AudioStreamType::NOTIFICATION},
226*4d7e907cSAndroid Build Coastguard Worker             {AUDIO_STREAM_BLUETOOTH_SCO_TAG, AudioStreamType::BLUETOOTH_SCO},
227*4d7e907cSAndroid Build Coastguard Worker             {AUDIO_STREAM_ENFORCED_AUDIBLE_TAG, AudioStreamType::ENFORCED_AUDIBLE},
228*4d7e907cSAndroid Build Coastguard Worker             {AUDIO_STREAM_DTMF_TAG, AudioStreamType::DTMF},
229*4d7e907cSAndroid Build Coastguard Worker             {AUDIO_STREAM_TTS_TAG, AudioStreamType::TTS},
230*4d7e907cSAndroid Build Coastguard Worker             {AUDIO_STREAM_ASSISTANT_TAG, AudioStreamType::ASSISTANT}};
231*4d7e907cSAndroid Build Coastguard Worker 
232*4d7e907cSAndroid Build Coastguard Worker     // see list of audio sources in audio_source_t:
233*4d7e907cSAndroid Build Coastguard Worker     // system/media/audio/include/system/audio_effects/audio_effects_conf.h
234*4d7e907cSAndroid Build Coastguard Worker     static const std::map<const std::string, AudioSource> sAudioSourceTable = {
235*4d7e907cSAndroid Build Coastguard Worker             {MIC_SRC_TAG, AudioSource::MIC},
236*4d7e907cSAndroid Build Coastguard Worker             {VOICE_UL_SRC_TAG, AudioSource::VOICE_UPLINK},
237*4d7e907cSAndroid Build Coastguard Worker             {VOICE_DL_SRC_TAG, AudioSource::VOICE_DOWNLINK},
238*4d7e907cSAndroid Build Coastguard Worker             {VOICE_CALL_SRC_TAG, AudioSource::VOICE_CALL},
239*4d7e907cSAndroid Build Coastguard Worker             {CAMCORDER_SRC_TAG, AudioSource::CAMCORDER},
240*4d7e907cSAndroid Build Coastguard Worker             {VOICE_REC_SRC_TAG, AudioSource::VOICE_RECOGNITION},
241*4d7e907cSAndroid Build Coastguard Worker             {VOICE_COMM_SRC_TAG, AudioSource::VOICE_COMMUNICATION},
242*4d7e907cSAndroid Build Coastguard Worker             {REMOTE_SUBMIX_SRC_TAG, AudioSource::REMOTE_SUBMIX},
243*4d7e907cSAndroid Build Coastguard Worker             {UNPROCESSED_SRC_TAG, AudioSource::UNPROCESSED},
244*4d7e907cSAndroid Build Coastguard Worker             {VOICE_PERFORMANCE_SRC_TAG, AudioSource::VOICE_PERFORMANCE}};
245*4d7e907cSAndroid Build Coastguard Worker 
246*4d7e907cSAndroid Build Coastguard Worker     if (typeTag == Processing::Type::streamType) {
247*4d7e907cSAndroid Build Coastguard Worker         auto typeIter = sAudioStreamTypeTable.find(type);
248*4d7e907cSAndroid Build Coastguard Worker         if (typeIter != sAudioStreamTypeTable.end()) {
249*4d7e907cSAndroid Build Coastguard Worker             return typeIter->second;
250*4d7e907cSAndroid Build Coastguard Worker         }
251*4d7e907cSAndroid Build Coastguard Worker     } else if (typeTag == Processing::Type::source) {
252*4d7e907cSAndroid Build Coastguard Worker         auto typeIter = sAudioSourceTable.find(type);
253*4d7e907cSAndroid Build Coastguard Worker         if (typeIter != sAudioSourceTable.end()) {
254*4d7e907cSAndroid Build Coastguard Worker             return typeIter->second;
255*4d7e907cSAndroid Build Coastguard Worker         }
256*4d7e907cSAndroid Build Coastguard Worker     } else if (typeTag == Processing::Type::device) {
257*4d7e907cSAndroid Build Coastguard Worker         audio_devices_t deviceType;
258*4d7e907cSAndroid Build Coastguard Worker         if (!audio_device_from_string(type.c_str(), &deviceType)) {
259*4d7e907cSAndroid Build Coastguard Worker             LOG(ERROR) << __func__ << "DeviceEffect: invalid type " << type;
260*4d7e907cSAndroid Build Coastguard Worker             return std::nullopt;
261*4d7e907cSAndroid Build Coastguard Worker         }
262*4d7e907cSAndroid Build Coastguard Worker         auto ret = ::aidl::android::legacy2aidl_audio_device_AudioDevice(deviceType, address);
263*4d7e907cSAndroid Build Coastguard Worker         if (!ret.ok()) {
264*4d7e907cSAndroid Build Coastguard Worker             LOG(ERROR) << __func__ << "DeviceEffect: Failed to get AudioDevice from type "
265*4d7e907cSAndroid Build Coastguard Worker                     << deviceType << ", address " << address;
266*4d7e907cSAndroid Build Coastguard Worker             return std::nullopt;
267*4d7e907cSAndroid Build Coastguard Worker         }
268*4d7e907cSAndroid Build Coastguard Worker         return ret.value();
269*4d7e907cSAndroid Build Coastguard Worker     }
270*4d7e907cSAndroid Build Coastguard Worker 
271*4d7e907cSAndroid Build Coastguard Worker     return std::nullopt;
272*4d7e907cSAndroid Build Coastguard Worker }
273*4d7e907cSAndroid Build Coastguard Worker 
parseProcessing(Processing::Type::Tag typeTag,const tinyxml2::XMLElement & xml)274*4d7e907cSAndroid Build Coastguard Worker bool EffectConfig::parseProcessing(Processing::Type::Tag typeTag, const tinyxml2::XMLElement& xml) {
275*4d7e907cSAndroid Build Coastguard Worker     LOG(VERBOSE) << __func__ << dump(xml);
276*4d7e907cSAndroid Build Coastguard Worker     const char* typeStr = xml.Attribute("type");
277*4d7e907cSAndroid Build Coastguard Worker     const char* addressStr = xml.Attribute("address");
278*4d7e907cSAndroid Build Coastguard Worker     // For device effect, device address is optional, match will be done for the given device type
279*4d7e907cSAndroid Build Coastguard Worker     // with empty address.
280*4d7e907cSAndroid Build Coastguard Worker     auto aidlType = stringToProcessingType(typeTag, typeStr, addressStr ? addressStr : "");
281*4d7e907cSAndroid Build Coastguard Worker     RETURN_VALUE_IF(!aidlType.has_value(), false, "illegalStreamType");
282*4d7e907cSAndroid Build Coastguard Worker     RETURN_VALUE_IF(0 != mProcessingMap.count(aidlType.value()), false, "duplicateStreamType");
283*4d7e907cSAndroid Build Coastguard Worker 
284*4d7e907cSAndroid Build Coastguard Worker     for (auto& apply : getChildren(xml, "apply")) {
285*4d7e907cSAndroid Build Coastguard Worker         const char* name = apply.get().Attribute("effect");
286*4d7e907cSAndroid Build Coastguard Worker         if (mEffectsMap.find(name) == mEffectsMap.end()) {
287*4d7e907cSAndroid Build Coastguard Worker             LOG(ERROR) << __func__ << " effect " << name << " doesn't exist, skipping";
288*4d7e907cSAndroid Build Coastguard Worker             continue;
289*4d7e907cSAndroid Build Coastguard Worker         }
290*4d7e907cSAndroid Build Coastguard Worker         RETURN_VALUE_IF(!name, false, "noEffectAttribute");
291*4d7e907cSAndroid Build Coastguard Worker         mProcessingMap[aidlType.value()].emplace_back(mEffectsMap[name]);
292*4d7e907cSAndroid Build Coastguard Worker     }
293*4d7e907cSAndroid Build Coastguard Worker     return true;
294*4d7e907cSAndroid Build Coastguard Worker }
295*4d7e907cSAndroid Build Coastguard Worker 
296*4d7e907cSAndroid Build Coastguard Worker const std::map<Processing::Type, std::vector<EffectConfig::EffectLibraries>>&
getProcessingMap() const297*4d7e907cSAndroid Build Coastguard Worker EffectConfig::getProcessingMap() const {
298*4d7e907cSAndroid Build Coastguard Worker     return mProcessingMap;
299*4d7e907cSAndroid Build Coastguard Worker }
300*4d7e907cSAndroid Build Coastguard Worker 
findUuid(const std::pair<std::string,struct EffectLibraries> & effectElem,AudioUuid * uuid)301*4d7e907cSAndroid Build Coastguard Worker bool EffectConfig::findUuid(const std::pair<std::string, struct EffectLibraries>& effectElem,
302*4d7e907cSAndroid Build Coastguard Worker                             AudioUuid* uuid) {
303*4d7e907cSAndroid Build Coastguard Worker // Difference from EFFECT_TYPE_LIST_DEF, there could be multiple name mapping to same Effect Type
304*4d7e907cSAndroid Build Coastguard Worker #define EFFECT_XML_TYPE_LIST_DEF(V)                        \
305*4d7e907cSAndroid Build Coastguard Worker     V("acoustic_echo_canceler", AcousticEchoCanceler)      \
306*4d7e907cSAndroid Build Coastguard Worker     V("automatic_gain_control_v1", AutomaticGainControlV1) \
307*4d7e907cSAndroid Build Coastguard Worker     V("automatic_gain_control_v2", AutomaticGainControlV2) \
308*4d7e907cSAndroid Build Coastguard Worker     V("bassboost", BassBoost)                              \
309*4d7e907cSAndroid Build Coastguard Worker     V("downmix", Downmix)                                  \
310*4d7e907cSAndroid Build Coastguard Worker     V("dynamics_processing", DynamicsProcessing)           \
311*4d7e907cSAndroid Build Coastguard Worker     V("equalizer", Equalizer)                              \
312*4d7e907cSAndroid Build Coastguard Worker     V("extensioneffect", Extension)                        \
313*4d7e907cSAndroid Build Coastguard Worker     V("haptic_generator", HapticGenerator)                 \
314*4d7e907cSAndroid Build Coastguard Worker     V("loudness_enhancer", LoudnessEnhancer)               \
315*4d7e907cSAndroid Build Coastguard Worker     V("env_reverb", EnvReverb)                             \
316*4d7e907cSAndroid Build Coastguard Worker     V("reverb_env_aux", EnvReverb)                         \
317*4d7e907cSAndroid Build Coastguard Worker     V("reverb_env_ins", EnvReverb)                         \
318*4d7e907cSAndroid Build Coastguard Worker     V("preset_reverb", PresetReverb)                       \
319*4d7e907cSAndroid Build Coastguard Worker     V("reverb_pre_aux", PresetReverb)                      \
320*4d7e907cSAndroid Build Coastguard Worker     V("reverb_pre_ins", PresetReverb)                      \
321*4d7e907cSAndroid Build Coastguard Worker     V("noise_suppression", NoiseSuppression)               \
322*4d7e907cSAndroid Build Coastguard Worker     V("spatializer", Spatializer)                          \
323*4d7e907cSAndroid Build Coastguard Worker     V("virtualizer", Virtualizer)                          \
324*4d7e907cSAndroid Build Coastguard Worker     V("visualizer", Visualizer)                            \
325*4d7e907cSAndroid Build Coastguard Worker     V("volume", Volume)
326*4d7e907cSAndroid Build Coastguard Worker 
327*4d7e907cSAndroid Build Coastguard Worker #define GENERATE_MAP_ENTRY_V(s, symbol) {s, &getEffectTypeUuid##symbol},
328*4d7e907cSAndroid Build Coastguard Worker 
329*4d7e907cSAndroid Build Coastguard Worker     const std::string xmlEffectName = effectElem.first;
330*4d7e907cSAndroid Build Coastguard Worker     typedef const AudioUuid& (*UuidGetter)(void);
331*4d7e907cSAndroid Build Coastguard Worker     static const std::map<std::string, UuidGetter> uuidMap{
332*4d7e907cSAndroid Build Coastguard Worker             // std::make_pair("s", &getEffectTypeUuidExtension)};
333*4d7e907cSAndroid Build Coastguard Worker             {EFFECT_XML_TYPE_LIST_DEF(GENERATE_MAP_ENTRY_V)}};
334*4d7e907cSAndroid Build Coastguard Worker     if (auto it = uuidMap.find(xmlEffectName); it != uuidMap.end()) {
335*4d7e907cSAndroid Build Coastguard Worker         *uuid = (*it->second)();
336*4d7e907cSAndroid Build Coastguard Worker         return true;
337*4d7e907cSAndroid Build Coastguard Worker     }
338*4d7e907cSAndroid Build Coastguard Worker 
339*4d7e907cSAndroid Build Coastguard Worker     const auto& libs = effectElem.second.libraries;
340*4d7e907cSAndroid Build Coastguard Worker     for (const auto& lib : libs) {
341*4d7e907cSAndroid Build Coastguard Worker         if (lib.type.has_value()) {
342*4d7e907cSAndroid Build Coastguard Worker             *uuid = lib.type.value();
343*4d7e907cSAndroid Build Coastguard Worker             return true;
344*4d7e907cSAndroid Build Coastguard Worker         }
345*4d7e907cSAndroid Build Coastguard Worker     }
346*4d7e907cSAndroid Build Coastguard Worker     return false;
347*4d7e907cSAndroid Build Coastguard Worker }
348*4d7e907cSAndroid Build Coastguard Worker 
dump(const tinyxml2::XMLElement & element,tinyxml2::XMLPrinter && printer) const349*4d7e907cSAndroid Build Coastguard Worker const char* EffectConfig::dump(const tinyxml2::XMLElement& element,
350*4d7e907cSAndroid Build Coastguard Worker                                tinyxml2::XMLPrinter&& printer) const {
351*4d7e907cSAndroid Build Coastguard Worker     element.Accept(&printer);
352*4d7e907cSAndroid Build Coastguard Worker     return printer.CStr();
353*4d7e907cSAndroid Build Coastguard Worker }
354*4d7e907cSAndroid Build Coastguard Worker 
355*4d7e907cSAndroid Build Coastguard Worker }  // namespace aidl::android::hardware::audio::effect
356