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