• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <inttypes.h>
2 
3 #include <unordered_set>
4 
5 #define LOG_TAG "AHAL_Config"
6 #include <android-base/logging.h>
7 #include <android-base/strings.h>
8 
9 #include <aidl/android/media/audio/common/AudioPort.h>
10 #include <aidl/android/media/audio/common/AudioPortConfig.h>
11 #include <media/AidlConversionCppNdk.h>
12 #include <media/TypeConverter.h>
13 
14 #include "core-impl/XmlConverter.h"
15 #include "core-impl/XsdcConversion.h"
16 
17 using aidl::android::media::audio::common::AudioChannelLayout;
18 using aidl::android::media::audio::common::AudioDevice;
19 using aidl::android::media::audio::common::AudioDeviceAddress;
20 using aidl::android::media::audio::common::AudioDeviceDescription;
21 using aidl::android::media::audio::common::AudioDeviceType;
22 using aidl::android::media::audio::common::AudioFormatDescription;
23 using aidl::android::media::audio::common::AudioFormatType;
24 using aidl::android::media::audio::common::AudioGain;
25 using aidl::android::media::audio::common::AudioHalCapCriterion;
26 using aidl::android::media::audio::common::AudioHalCapCriterionType;
27 using aidl::android::media::audio::common::AudioHalVolumeCurve;
28 using aidl::android::media::audio::common::AudioIoFlags;
29 using aidl::android::media::audio::common::AudioPort;
30 using aidl::android::media::audio::common::AudioPortConfig;
31 using aidl::android::media::audio::common::AudioPortDeviceExt;
32 using aidl::android::media::audio::common::AudioPortExt;
33 using aidl::android::media::audio::common::AudioPortMixExt;
34 using aidl::android::media::audio::common::AudioProfile;
35 using ::android::BAD_VALUE;
36 using ::android::base::unexpected;
37 
38 namespace ap_xsd = android::audio::policy::configuration;
39 namespace eng_xsd = android::audio::policy::engine::configuration;
40 
41 namespace aidl::android::hardware::audio::core::internal {
42 
assertNonEmpty(const std::string & s)43 inline ConversionResult<std::string> assertNonEmpty(const std::string& s) {
44     if (s.empty()) {
45         LOG(ERROR) << __func__ << " Review Audio Policy config: "
46                    << " empty string is not valid.";
47         return unexpected(BAD_VALUE);
48     }
49     return s;
50 }
51 
52 #define NON_EMPTY_STRING_OR_FATAL(s) VALUE_OR_FATAL(assertNonEmpty(s))
53 
convertAudioFormatToAidl(const std::string & xsdcFormat)54 ConversionResult<AudioFormatDescription> convertAudioFormatToAidl(const std::string& xsdcFormat) {
55     audio_format_t legacyFormat = ::android::formatFromString(xsdcFormat, AUDIO_FORMAT_DEFAULT);
56     ConversionResult<AudioFormatDescription> result =
57             legacy2aidl_audio_format_t_AudioFormatDescription(legacyFormat);
58     if ((legacyFormat == AUDIO_FORMAT_DEFAULT && xsdcFormat.compare("AUDIO_FORMAT_DEFAULT") != 0) ||
59         !result.ok()) {
60         LOG(ERROR) << __func__ << " Review Audio Policy config: " << xsdcFormat
61                    << " is not a valid audio format.";
62         return unexpected(BAD_VALUE);
63     }
64     return result;
65 }
66 
getAttachedDevices(const ap_xsd::Modules::Module & moduleConfig)67 std::unordered_set<std::string> getAttachedDevices(const ap_xsd::Modules::Module& moduleConfig) {
68     std::unordered_set<std::string> attachedDeviceSet;
69     if (moduleConfig.hasAttachedDevices()) {
70         for (const ap_xsd::AttachedDevices& attachedDevices : moduleConfig.getAttachedDevices()) {
71             if (attachedDevices.hasItem()) {
72                 attachedDeviceSet.insert(attachedDevices.getItem().begin(),
73                                          attachedDevices.getItem().end());
74             }
75         }
76     }
77     return attachedDeviceSet;
78 }
79 
convertDeviceTypeToAidl(const std::string & xType)80 ConversionResult<AudioDeviceDescription> convertDeviceTypeToAidl(const std::string& xType) {
81     audio_devices_t legacyDeviceType = AUDIO_DEVICE_NONE;
82     ::android::DeviceConverter::fromString(xType, legacyDeviceType);
83     ConversionResult<AudioDeviceDescription> result =
84             legacy2aidl_audio_devices_t_AudioDeviceDescription(legacyDeviceType);
85     if ((legacyDeviceType == AUDIO_DEVICE_NONE) || !result.ok()) {
86         LOG(ERROR) << __func__ << " Review Audio Policy config: " << xType
87                    << " is not a valid device type.";
88         return unexpected(BAD_VALUE);
89     }
90     return result;
91 }
92 
createAudioDevice(const ap_xsd::DevicePorts::DevicePort & xDevicePort)93 ConversionResult<AudioDevice> createAudioDevice(
94         const ap_xsd::DevicePorts::DevicePort& xDevicePort) {
95     AudioDevice device = {
96             .type = VALUE_OR_FATAL(convertDeviceTypeToAidl(xDevicePort.getType())),
97             .address = xDevicePort.hasAddress()
98                                ? AudioDeviceAddress::make<AudioDeviceAddress::Tag::id>(
99                                          xDevicePort.getAddress())
100                                : AudioDeviceAddress{}};
101     if (device.type.type == AudioDeviceType::IN_MICROPHONE && device.type.connection.empty()) {
102         device.address = "bottom";
103     } else if (device.type.type == AudioDeviceType::IN_MICROPHONE_BACK &&
104                device.type.connection.empty()) {
105         device.address = "back";
106     }
107     return device;
108 }
109 
createAudioPortExt(const ap_xsd::DevicePorts::DevicePort & xDevicePort,const std::string & xDefaultOutputDevice)110 ConversionResult<AudioPortExt> createAudioPortExt(
111         const ap_xsd::DevicePorts::DevicePort& xDevicePort,
112         const std::string& xDefaultOutputDevice) {
113     AudioPortDeviceExt deviceExt = {
114             .device = VALUE_OR_FATAL(createAudioDevice(xDevicePort)),
115             .flags = (xDevicePort.getTagName() == xDefaultOutputDevice)
116                              ? 1 << AudioPortDeviceExt::FLAG_INDEX_DEFAULT_DEVICE
117                              : 0,
118             .encodedFormats =
119                     xDevicePort.hasEncodedFormats()
120                             ? VALUE_OR_FATAL(
121                                       (convertCollectionToAidl<std::string, AudioFormatDescription>(
122                                               xDevicePort.getEncodedFormats(),
123                                               &convertAudioFormatToAidl)))
124                             : std::vector<AudioFormatDescription>{},
125     };
126     return AudioPortExt::make<AudioPortExt::Tag::device>(deviceExt);
127 }
128 
createAudioPortExt(const ap_xsd::MixPorts::MixPort & xMixPort)129 ConversionResult<AudioPortExt> createAudioPortExt(const ap_xsd::MixPorts::MixPort& xMixPort) {
130     AudioPortMixExt mixExt = {
131             .maxOpenStreamCount =
132                     xMixPort.hasMaxOpenCount() ? static_cast<int>(xMixPort.getMaxOpenCount()) : 0,
133             .maxActiveStreamCount = xMixPort.hasMaxActiveCount()
134                                             ? static_cast<int>(xMixPort.getMaxActiveCount())
135                                             : 1,
136             .recommendedMuteDurationMs =
137                     xMixPort.hasRecommendedMuteDurationMs()
138                             ? static_cast<int>(xMixPort.getRecommendedMuteDurationMs())
139                             : 0};
140     return AudioPortExt::make<AudioPortExt::Tag::mix>(mixExt);
141 }
142 
convertGainModeToAidl(const std::vector<ap_xsd::AudioGainMode> & gainModeVec)143 ConversionResult<int> convertGainModeToAidl(const std::vector<ap_xsd::AudioGainMode>& gainModeVec) {
144     int gainModeMask = 0;
145     for (const ap_xsd::AudioGainMode& gainMode : gainModeVec) {
146         audio_gain_mode_t legacyGainMode;
147         if (::android::GainModeConverter::fromString(ap_xsd::toString(gainMode), legacyGainMode)) {
148             gainModeMask |= static_cast<int>(legacyGainMode);
149         }
150     }
151     return gainModeMask;
152 }
153 
convertChannelMaskToAidl(const ap_xsd::AudioChannelMask & xChannelMask)154 ConversionResult<AudioChannelLayout> convertChannelMaskToAidl(
155         const ap_xsd::AudioChannelMask& xChannelMask) {
156     std::string xChannelMaskLiteral = ap_xsd::toString(xChannelMask);
157     audio_channel_mask_t legacyChannelMask = ::android::channelMaskFromString(xChannelMaskLiteral);
158     ConversionResult<AudioChannelLayout> result =
159             legacy2aidl_audio_channel_mask_t_AudioChannelLayout(
160                     legacyChannelMask,
161                     /* isInput= */ xChannelMaskLiteral.find("AUDIO_CHANNEL_IN_") == 0);
162     if ((legacyChannelMask == AUDIO_CHANNEL_INVALID) || !result.ok()) {
163         LOG(ERROR) << __func__ << " Review Audio Policy config: " << xChannelMaskLiteral
164                    << " is not a valid audio channel mask.";
165         return unexpected(BAD_VALUE);
166     }
167     return result;
168 }
169 
convertGainToAidl(const ap_xsd::Gains::Gain & xGain)170 ConversionResult<AudioGain> convertGainToAidl(const ap_xsd::Gains::Gain& xGain) {
171     return AudioGain{
172             .mode = VALUE_OR_FATAL(convertGainModeToAidl(xGain.getMode())),
173             .channelMask =
174                     xGain.hasChannel_mask()
175                             ? VALUE_OR_FATAL(convertChannelMaskToAidl(xGain.getChannel_mask()))
176                             : AudioChannelLayout{},
177             .minValue = xGain.hasMinValueMB() ? xGain.getMinValueMB() : 0,
178             .maxValue = xGain.hasMaxValueMB() ? xGain.getMaxValueMB() : 0,
179             .defaultValue = xGain.hasDefaultValueMB() ? xGain.getDefaultValueMB() : 0,
180             .stepValue = xGain.hasStepValueMB() ? xGain.getStepValueMB() : 0,
181             .minRampMs = xGain.hasMinRampMs() ? xGain.getMinRampMs() : 0,
182             .maxRampMs = xGain.hasMaxRampMs() ? xGain.getMaxRampMs() : 0,
183             .useForVolume = xGain.hasUseForVolume() ? xGain.getUseForVolume() : false,
184     };
185 }
186 
convertAudioProfileToAidl(const ap_xsd::Profile & xProfile)187 ConversionResult<AudioProfile> convertAudioProfileToAidl(const ap_xsd::Profile& xProfile) {
188     return AudioProfile{
189             .format = xProfile.hasFormat()
190                               ? VALUE_OR_FATAL(convertAudioFormatToAidl(xProfile.getFormat()))
191                               : AudioFormatDescription{},
192             .channelMasks =
193                     xProfile.hasChannelMasks()
194                             ? VALUE_OR_FATAL((convertCollectionToAidl<ap_xsd::AudioChannelMask,
195                                                                       AudioChannelLayout>(
196                                       xProfile.getChannelMasks(), &convertChannelMaskToAidl)))
197                             : std::vector<AudioChannelLayout>{},
198             .sampleRates = xProfile.hasSamplingRates()
199                                    ? VALUE_OR_FATAL((convertCollectionToAidl<int64_t, int>(
200                                              xProfile.getSamplingRates(),
201                                              [](const int64_t x) -> int { return x; })))
202                                    : std::vector<int>{}};
203 }
204 
convertIoFlagsToAidl(const std::vector<ap_xsd::AudioInOutFlag> & flags,const ap_xsd::Role role,bool flagsForMixPort)205 ConversionResult<AudioIoFlags> convertIoFlagsToAidl(
206         const std::vector<ap_xsd::AudioInOutFlag>& flags, const ap_xsd::Role role,
207         bool flagsForMixPort) {
208     int legacyFlagMask = 0;
209     if ((role == ap_xsd::Role::sink && flagsForMixPort) ||
210         (role == ap_xsd::Role::source && !flagsForMixPort)) {
211         for (const ap_xsd::AudioInOutFlag& flag : flags) {
212             audio_input_flags_t legacyFlag;
213             if (::android::InputFlagConverter::fromString(ap_xsd::toString(flag), legacyFlag)) {
214                 legacyFlagMask |= static_cast<int>(legacyFlag);
215             }
216         }
217         return AudioIoFlags::make<AudioIoFlags::Tag::input>(
218                 VALUE_OR_FATAL(legacy2aidl_audio_input_flags_t_int32_t_mask(
219                         static_cast<audio_input_flags_t>(legacyFlagMask))));
220     } else {
221         for (const ap_xsd::AudioInOutFlag& flag : flags) {
222             audio_output_flags_t legacyFlag;
223             if (::android::OutputFlagConverter::fromString(ap_xsd::toString(flag), legacyFlag)) {
224                 legacyFlagMask |= static_cast<int>(legacyFlag);
225             }
226         }
227         return AudioIoFlags::make<AudioIoFlags::Tag::output>(
228                 VALUE_OR_FATAL(legacy2aidl_audio_output_flags_t_int32_t_mask(
229                         static_cast<audio_output_flags_t>(legacyFlagMask))));
230     }
231 }
232 
convertDevicePortToAidl(const ap_xsd::DevicePorts::DevicePort & xDevicePort,const std::string & xDefaultOutputDevice,int32_t & nextPortId)233 ConversionResult<AudioPort> convertDevicePortToAidl(
234         const ap_xsd::DevicePorts::DevicePort& xDevicePort, const std::string& xDefaultOutputDevice,
235         int32_t& nextPortId) {
236     return AudioPort{
237             .id = nextPortId++,
238             .name = NON_EMPTY_STRING_OR_FATAL(xDevicePort.getTagName()),
239             .profiles = VALUE_OR_FATAL((convertCollectionToAidl<ap_xsd::Profile, AudioProfile>(
240                     xDevicePort.getProfile(), convertAudioProfileToAidl))),
241             .flags = VALUE_OR_FATAL(convertIoFlagsToAidl({}, xDevicePort.getRole(), false)),
242             .gains = VALUE_OR_FATAL(
243                     (convertWrappedCollectionToAidl<ap_xsd::Gains, ap_xsd::Gains::Gain, AudioGain>(
244                             xDevicePort.getGains(), &ap_xsd::Gains::getGain, convertGainToAidl))),
245 
246             .ext = VALUE_OR_FATAL(createAudioPortExt(xDevicePort, xDefaultOutputDevice))};
247 }
248 
convertDevicePortsInModuleToAidl(const ap_xsd::Modules::Module & xModuleConfig,int32_t & nextPortId)249 ConversionResult<std::vector<AudioPort>> convertDevicePortsInModuleToAidl(
250         const ap_xsd::Modules::Module& xModuleConfig, int32_t& nextPortId) {
251     std::vector<AudioPort> audioPortVec;
252     std::vector<ap_xsd::DevicePorts> xDevicePortsVec = xModuleConfig.getDevicePorts();
253     if (xDevicePortsVec.size() > 1) {
254         LOG(ERROR) << __func__ << "Having multiple '<devicePorts>' elements is not allowed, found: "
255                    << xDevicePortsVec.size();
256         return unexpected(BAD_VALUE);
257     }
258     if (!xDevicePortsVec.empty()) {
259         const std::string xDefaultOutputDevice = xModuleConfig.hasDefaultOutputDevice()
260                                                          ? xModuleConfig.getDefaultOutputDevice()
261                                                          : "";
262         audioPortVec.reserve(xDevicePortsVec[0].getDevicePort().size());
263         for (const ap_xsd::DevicePorts& xDevicePortsType : xDevicePortsVec) {
264             for (const ap_xsd::DevicePorts::DevicePort& xDevicePort :
265                  xDevicePortsType.getDevicePort()) {
266                 audioPortVec.push_back(VALUE_OR_FATAL(
267                         convertDevicePortToAidl(xDevicePort, xDefaultOutputDevice, nextPortId)));
268             }
269         }
270     }
271     const std::unordered_set<std::string> xAttachedDeviceSet = getAttachedDevices(xModuleConfig);
272     for (const auto& port : audioPortVec) {
273         const auto& devicePort = port.ext.get<AudioPortExt::device>();
274         if (xAttachedDeviceSet.count(port.name) != devicePort.device.type.connection.empty()) {
275             LOG(ERROR) << __func__ << ": Review Audio Policy config: <attachedDevices> "
276                        << "list is incorrect or devicePort \"" << port.name
277                        << "\" type= " << devicePort.device.type.toString() << " is incorrect.";
278             return unexpected(BAD_VALUE);
279         }
280     }
281     return audioPortVec;
282 }
283 
convertMixPortToAidl(const ap_xsd::MixPorts::MixPort & xMixPort,int32_t & nextPortId)284 ConversionResult<AudioPort> convertMixPortToAidl(const ap_xsd::MixPorts::MixPort& xMixPort,
285                                                  int32_t& nextPortId) {
286     return AudioPort{
287             .id = nextPortId++,
288             .name = NON_EMPTY_STRING_OR_FATAL(xMixPort.getName()),
289             .profiles = VALUE_OR_FATAL((convertCollectionToAidl<ap_xsd::Profile, AudioProfile>(
290                     xMixPort.getProfile(), convertAudioProfileToAidl))),
291             .flags = xMixPort.hasFlags()
292                              ? VALUE_OR_FATAL(convertIoFlagsToAidl(xMixPort.getFlags(),
293                                                                    xMixPort.getRole(), true))
294                              : VALUE_OR_FATAL(convertIoFlagsToAidl({}, xMixPort.getRole(), true)),
295             .gains = VALUE_OR_FATAL(
296                     (convertWrappedCollectionToAidl<ap_xsd::Gains, ap_xsd::Gains::Gain, AudioGain>(
297                             xMixPort.getGains(), &ap_xsd::Gains::getGain, &convertGainToAidl))),
298             .ext = VALUE_OR_FATAL(createAudioPortExt(xMixPort)),
299     };
300 }
301 
convertMixPortsInModuleToAidl(const ap_xsd::Modules::Module & xModuleConfig,int32_t & nextPortId)302 ConversionResult<std::vector<AudioPort>> convertMixPortsInModuleToAidl(
303         const ap_xsd::Modules::Module& xModuleConfig, int32_t& nextPortId) {
304     std::vector<AudioPort> audioPortVec;
305     std::vector<ap_xsd::MixPorts> xMixPortsVec = xModuleConfig.getMixPorts();
306     if (xMixPortsVec.size() > 1) {
307         LOG(ERROR) << __func__ << "Having multiple '<mixPorts>' elements is not allowed, found: "
308                    << xMixPortsVec.size();
309         return unexpected(BAD_VALUE);
310     }
311     if (!xMixPortsVec.empty()) {
312         audioPortVec.reserve(xMixPortsVec[0].getMixPort().size());
313         for (const ap_xsd::MixPorts& xMixPortsType : xMixPortsVec) {
314             for (const ap_xsd::MixPorts::MixPort& xMixPort : xMixPortsType.getMixPort()) {
315                 audioPortVec.push_back(VALUE_OR_FATAL(convertMixPortToAidl(xMixPort, nextPortId)));
316             }
317         }
318     }
319     return audioPortVec;
320 }
321 
getSinkPortId(const ap_xsd::Routes::Route & xRoute,const std::unordered_map<std::string,int32_t> & portMap)322 ConversionResult<int32_t> getSinkPortId(const ap_xsd::Routes::Route& xRoute,
323                                         const std::unordered_map<std::string, int32_t>& portMap) {
324     auto portMapIter = portMap.find(xRoute.getSink());
325     if (portMapIter == portMap.end()) {
326         LOG(ERROR) << __func__ << " Review Audio Policy config: audio route"
327                    << "has sink: " << xRoute.getSink()
328                    << " which is neither a device port nor mix port.";
329         return unexpected(BAD_VALUE);
330     }
331     return portMapIter->second;
332 }
333 
getSourcePortIds(const ap_xsd::Routes::Route & xRoute,const std::unordered_map<std::string,int32_t> & portMap)334 ConversionResult<std::vector<int32_t>> getSourcePortIds(
335         const ap_xsd::Routes::Route& xRoute,
336         const std::unordered_map<std::string, int32_t>& portMap) {
337     std::vector<int32_t> sourcePortIds;
338     for (const std::string& rawSource : ::android::base::Split(xRoute.getSources(), ",")) {
339         const std::string source = ::android::base::Trim(rawSource);
340         auto portMapIter = portMap.find(source);
341         if (portMapIter == portMap.end()) {
342             LOG(ERROR) << __func__ << " Review Audio Policy config: audio route"
343                        << "has source \"" << source
344                        << "\" which is neither a device port nor mix port.";
345             return unexpected(BAD_VALUE);
346         }
347         sourcePortIds.push_back(portMapIter->second);
348     }
349     return sourcePortIds;
350 }
351 
convertRouteToAidl(const ap_xsd::Routes::Route & xRoute,const std::vector<AudioPort> & aidlAudioPorts)352 ConversionResult<AudioRoute> convertRouteToAidl(const ap_xsd::Routes::Route& xRoute,
353                                                 const std::vector<AudioPort>& aidlAudioPorts) {
354     std::unordered_map<std::string, int32_t> portMap;
355     for (const AudioPort& port : aidlAudioPorts) {
356         portMap.insert({port.name, port.id});
357     }
358     return AudioRoute{.sourcePortIds = VALUE_OR_FATAL(getSourcePortIds(xRoute, portMap)),
359                       .sinkPortId = VALUE_OR_FATAL(getSinkPortId(xRoute, portMap)),
360                       .isExclusive = (xRoute.getType() == ap_xsd::MixType::mux)};
361 }
362 
convertRoutesInModuleToAidl(const ap_xsd::Modules::Module & xModuleConfig,const std::vector<AudioPort> & aidlAudioPorts)363 ConversionResult<std::vector<AudioRoute>> convertRoutesInModuleToAidl(
364         const ap_xsd::Modules::Module& xModuleConfig,
365         const std::vector<AudioPort>& aidlAudioPorts) {
366     std::vector<AudioRoute> audioRouteVec;
367     std::vector<ap_xsd::Routes> xRoutesVec = xModuleConfig.getRoutes();
368     if (!xRoutesVec.empty()) {
369         /*
370          * xRoutesVec likely only contains one element; that is, it's
371          * likely that all ap_xsd::Routes::MixPort types that we need to convert
372          * are inside of xRoutesVec[0].
373          */
374         audioRouteVec.reserve(xRoutesVec[0].getRoute().size());
375         for (const ap_xsd::Routes& xRoutesType : xRoutesVec) {
376             for (const ap_xsd::Routes::Route& xRoute : xRoutesType.getRoute()) {
377                 audioRouteVec.push_back(VALUE_OR_FATAL(convertRouteToAidl(xRoute, aidlAudioPorts)));
378             }
379         }
380     }
381     return audioRouteVec;
382 }
383 
convertModuleConfigToAidl(const ap_xsd::Modules::Module & xModuleConfig)384 ConversionResult<std::unique_ptr<Module::Configuration>> convertModuleConfigToAidl(
385         const ap_xsd::Modules::Module& xModuleConfig) {
386     auto result = std::make_unique<Module::Configuration>();
387     auto& aidlModuleConfig = *result;
388     std::vector<AudioPort> devicePorts = VALUE_OR_FATAL(
389             convertDevicePortsInModuleToAidl(xModuleConfig, aidlModuleConfig.nextPortId));
390 
391     // The XML config does not specify the default input device.
392     // Assign the first attached input device as the default.
393     for (auto& port : devicePorts) {
394         if (port.flags.getTag() != AudioIoFlags::input) continue;
395         auto& deviceExt = port.ext.get<AudioPortExt::device>();
396         if (!deviceExt.device.type.connection.empty()) continue;
397         deviceExt.flags |= 1 << AudioPortDeviceExt::FLAG_INDEX_DEFAULT_DEVICE;
398         break;
399     }
400 
401     std::vector<AudioPort> mixPorts = VALUE_OR_FATAL(
402             convertMixPortsInModuleToAidl(xModuleConfig, aidlModuleConfig.nextPortId));
403     aidlModuleConfig.ports.reserve(devicePorts.size() + mixPorts.size());
404     aidlModuleConfig.ports.insert(aidlModuleConfig.ports.end(), devicePorts.begin(),
405                                   devicePorts.end());
406     aidlModuleConfig.ports.insert(aidlModuleConfig.ports.end(), mixPorts.begin(), mixPorts.end());
407 
408     aidlModuleConfig.routes =
409             VALUE_OR_FATAL(convertRoutesInModuleToAidl(xModuleConfig, aidlModuleConfig.ports));
410     return result;
411 }
412 
convertCapCriterionToAidl(const eng_xsd::CriterionType & xsdcCriterion)413 ConversionResult<AudioHalCapCriterion> convertCapCriterionToAidl(
414         const eng_xsd::CriterionType& xsdcCriterion) {
415     AudioHalCapCriterion aidlCapCriterion;
416     aidlCapCriterion.name = xsdcCriterion.getName();
417     aidlCapCriterion.criterionTypeName = xsdcCriterion.getType();
418     aidlCapCriterion.defaultLiteralValue = xsdcCriterion.get_default();
419     return aidlCapCriterion;
420 }
421 
convertCriterionTypeValueToAidl(const eng_xsd::ValueType & xsdcCriterionTypeValue)422 ConversionResult<std::string> convertCriterionTypeValueToAidl(
423         const eng_xsd::ValueType& xsdcCriterionTypeValue) {
424     return xsdcCriterionTypeValue.getLiteral();
425 }
426 
convertCapCriterionTypeToAidl(const eng_xsd::CriterionTypeType & xsdcCriterionType)427 ConversionResult<AudioHalCapCriterionType> convertCapCriterionTypeToAidl(
428         const eng_xsd::CriterionTypeType& xsdcCriterionType) {
429     AudioHalCapCriterionType aidlCapCriterionType;
430     aidlCapCriterionType.name = xsdcCriterionType.getName();
431     aidlCapCriterionType.isInclusive = !(static_cast<bool>(xsdcCriterionType.getType()));
432     aidlCapCriterionType.values = VALUE_OR_RETURN(
433             (convertWrappedCollectionToAidl<eng_xsd::ValuesType, eng_xsd::ValueType, std::string>(
434                     xsdcCriterionType.getValues(), &eng_xsd::ValuesType::getValue,
435                     &convertCriterionTypeValueToAidl)));
436     return aidlCapCriterionType;
437 }
438 
convertCurvePointToAidl(const std::string & xsdcCurvePoint)439 ConversionResult<AudioHalVolumeCurve::CurvePoint> convertCurvePointToAidl(
440         const std::string& xsdcCurvePoint) {
441     AudioHalVolumeCurve::CurvePoint aidlCurvePoint{};
442     if ((sscanf(xsdcCurvePoint.c_str(), "%" SCNd8 ",%d", &aidlCurvePoint.index,
443                 &aidlCurvePoint.attenuationMb) != 2) ||
444         (aidlCurvePoint.index < AudioHalVolumeCurve::CurvePoint::MIN_INDEX) ||
445         (aidlCurvePoint.index > AudioHalVolumeCurve::CurvePoint::MAX_INDEX)) {
446         LOG(ERROR) << __func__ << " Review Audio Policy config: volume curve point:"
447                    << "\"" << xsdcCurvePoint << "\" is invalid";
448         return unexpected(BAD_VALUE);
449     }
450     return aidlCurvePoint;
451 }
452 }  // namespace aidl::android::hardware::audio::core::internal
453