blob: 9e303471cdfaec87861f9efa13769e728b4bac24 [file] [log] [blame]
Lorena Torres-Huerta394e2522022-12-20 02:21:41 +00001#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
17using aidl::android::media::audio::common::AudioChannelLayout;
18using aidl::android::media::audio::common::AudioDevice;
19using aidl::android::media::audio::common::AudioDeviceAddress;
20using aidl::android::media::audio::common::AudioDeviceDescription;
21using aidl::android::media::audio::common::AudioDeviceType;
22using aidl::android::media::audio::common::AudioFormatDescription;
23using aidl::android::media::audio::common::AudioFormatType;
24using aidl::android::media::audio::common::AudioGain;
25using aidl::android::media::audio::common::AudioHalCapCriterion;
26using aidl::android::media::audio::common::AudioHalCapCriterionType;
27using aidl::android::media::audio::common::AudioHalVolumeCurve;
28using aidl::android::media::audio::common::AudioIoFlags;
29using aidl::android::media::audio::common::AudioPort;
30using aidl::android::media::audio::common::AudioPortConfig;
31using aidl::android::media::audio::common::AudioPortDeviceExt;
32using aidl::android::media::audio::common::AudioPortExt;
33using aidl::android::media::audio::common::AudioPortMixExt;
34using aidl::android::media::audio::common::AudioProfile;
35using ::android::BAD_VALUE;
36using ::android::base::unexpected;
37
38namespace ap_xsd = android::audio::policy::configuration;
39namespace eng_xsd = android::audio::policy::engine::configuration;
40
41namespace aidl::android::hardware::audio::core::internal {
42
43inline 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
54ConversionResult<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
67std::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
80ConversionResult<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
93ConversionResult<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
110ConversionResult<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
129ConversionResult<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
143ConversionResult<int> convertGainModeToAidl(const std::vector<ap_xsd::AudioGainMode>& gainModeVec) {
Lorena Torres-Huerta394e2522022-12-20 02:21:41 +0000144 int gainModeMask = 0;
145 for (const ap_xsd::AudioGainMode& gainMode : gainModeVec) {
Mikhail Naganovcc21b6f2023-10-17 19:39:27 -0700146 audio_gain_mode_t legacyGainMode;
147 if (::android::GainModeConverter::fromString(ap_xsd::toString(gainMode), legacyGainMode)) {
148 gainModeMask |= static_cast<int>(legacyGainMode);
149 }
Lorena Torres-Huerta394e2522022-12-20 02:21:41 +0000150 }
151 return gainModeMask;
152}
153
154ConversionResult<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
170ConversionResult<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
187ConversionResult<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
205ConversionResult<AudioIoFlags> convertIoFlagsToAidl(
206 const std::vector<ap_xsd::AudioInOutFlag>& flags, const ap_xsd::Role role,
207 bool flagsForMixPort) {
Lorena Torres-Huerta394e2522022-12-20 02:21:41 +0000208 int flagMask = 0;
209 if ((role == ap_xsd::Role::sink && flagsForMixPort) ||
210 (role == ap_xsd::Role::source && !flagsForMixPort)) {
211 for (const ap_xsd::AudioInOutFlag& flag : flags) {
Mikhail Naganovcc21b6f2023-10-17 19:39:27 -0700212 audio_input_flags_t legacyFlag;
213 if (::android::InputFlagConverter::fromString(ap_xsd::toString(flag), legacyFlag)) {
214 flagMask |= static_cast<int>(legacyFlag);
215 }
Lorena Torres-Huerta394e2522022-12-20 02:21:41 +0000216 }
217 return AudioIoFlags::make<AudioIoFlags::Tag::input>(flagMask);
218 } else {
219 for (const ap_xsd::AudioInOutFlag& flag : flags) {
Mikhail Naganovcc21b6f2023-10-17 19:39:27 -0700220 audio_output_flags_t legacyFlag;
221 if (::android::OutputFlagConverter::fromString(ap_xsd::toString(flag), legacyFlag)) {
222 flagMask |= static_cast<int>(legacyFlag);
223 }
Lorena Torres-Huerta394e2522022-12-20 02:21:41 +0000224 }
Mikhail Naganovcc21b6f2023-10-17 19:39:27 -0700225 return AudioIoFlags::make<AudioIoFlags::Tag::output>(flagMask);
Lorena Torres-Huerta394e2522022-12-20 02:21:41 +0000226 }
Lorena Torres-Huerta394e2522022-12-20 02:21:41 +0000227}
228
229ConversionResult<AudioPort> convertDevicePortToAidl(
230 const ap_xsd::DevicePorts::DevicePort& xDevicePort, const std::string& xDefaultOutputDevice,
231 int32_t& nextPortId) {
232 return AudioPort{
233 .id = nextPortId++,
234 .name = NON_EMPTY_STRING_OR_FATAL(xDevicePort.getTagName()),
235 .profiles = VALUE_OR_FATAL((convertCollectionToAidl<ap_xsd::Profile, AudioProfile>(
236 xDevicePort.getProfile(), convertAudioProfileToAidl))),
237 .flags = VALUE_OR_FATAL(convertIoFlagsToAidl({}, xDevicePort.getRole(), false)),
238 .gains = VALUE_OR_FATAL(
239 (convertWrappedCollectionToAidl<ap_xsd::Gains, ap_xsd::Gains::Gain, AudioGain>(
240 xDevicePort.getGains(), &ap_xsd::Gains::getGain, convertGainToAidl))),
241
242 .ext = VALUE_OR_FATAL(createAudioPortExt(xDevicePort, xDefaultOutputDevice))};
243}
244
245ConversionResult<std::vector<AudioPort>> convertDevicePortsInModuleToAidl(
246 const ap_xsd::Modules::Module& xModuleConfig, int32_t& nextPortId) {
247 std::vector<AudioPort> audioPortVec;
248 std::vector<ap_xsd::DevicePorts> xDevicePortsVec = xModuleConfig.getDevicePorts();
249 if (xDevicePortsVec.size() > 1) {
250 LOG(ERROR) << __func__ << "Having multiple '<devicePorts>' elements is not allowed, found: "
251 << xDevicePortsVec.size();
252 return unexpected(BAD_VALUE);
253 }
254 if (!xDevicePortsVec.empty()) {
255 const std::string xDefaultOutputDevice = xModuleConfig.hasDefaultOutputDevice()
256 ? xModuleConfig.getDefaultOutputDevice()
257 : "";
258 audioPortVec.reserve(xDevicePortsVec[0].getDevicePort().size());
259 for (const ap_xsd::DevicePorts& xDevicePortsType : xDevicePortsVec) {
260 for (const ap_xsd::DevicePorts::DevicePort& xDevicePort :
261 xDevicePortsType.getDevicePort()) {
262 audioPortVec.push_back(VALUE_OR_FATAL(
263 convertDevicePortToAidl(xDevicePort, xDefaultOutputDevice, nextPortId)));
264 }
265 }
266 }
267 const std::unordered_set<std::string> xAttachedDeviceSet = getAttachedDevices(xModuleConfig);
268 for (const auto& port : audioPortVec) {
269 const auto& devicePort = port.ext.get<AudioPortExt::device>();
270 if (xAttachedDeviceSet.count(port.name) != devicePort.device.type.connection.empty()) {
271 LOG(ERROR) << __func__ << ": Review Audio Policy config: <attachedDevices> "
272 << "list is incorrect or devicePort \"" << port.name
273 << "\" type= " << devicePort.device.type.toString() << " is incorrect.";
274 return unexpected(BAD_VALUE);
275 }
276 }
277 return audioPortVec;
278}
279
280ConversionResult<AudioPort> convertMixPortToAidl(const ap_xsd::MixPorts::MixPort& xMixPort,
281 int32_t& nextPortId) {
282 return AudioPort{
283 .id = nextPortId++,
284 .name = NON_EMPTY_STRING_OR_FATAL(xMixPort.getName()),
285 .profiles = VALUE_OR_FATAL((convertCollectionToAidl<ap_xsd::Profile, AudioProfile>(
286 xMixPort.getProfile(), convertAudioProfileToAidl))),
287 .flags = xMixPort.hasFlags()
288 ? VALUE_OR_FATAL(convertIoFlagsToAidl(xMixPort.getFlags(),
289 xMixPort.getRole(), true))
290 : VALUE_OR_FATAL(convertIoFlagsToAidl({}, xMixPort.getRole(), true)),
291 .gains = VALUE_OR_FATAL(
292 (convertWrappedCollectionToAidl<ap_xsd::Gains, ap_xsd::Gains::Gain, AudioGain>(
293 xMixPort.getGains(), &ap_xsd::Gains::getGain, &convertGainToAidl))),
294 .ext = VALUE_OR_FATAL(createAudioPortExt(xMixPort)),
295 };
296}
297
298ConversionResult<std::vector<AudioPort>> convertMixPortsInModuleToAidl(
299 const ap_xsd::Modules::Module& xModuleConfig, int32_t& nextPortId) {
300 std::vector<AudioPort> audioPortVec;
301 std::vector<ap_xsd::MixPorts> xMixPortsVec = xModuleConfig.getMixPorts();
302 if (xMixPortsVec.size() > 1) {
303 LOG(ERROR) << __func__ << "Having multiple '<mixPorts>' elements is not allowed, found: "
304 << xMixPortsVec.size();
305 return unexpected(BAD_VALUE);
306 }
307 if (!xMixPortsVec.empty()) {
308 audioPortVec.reserve(xMixPortsVec[0].getMixPort().size());
309 for (const ap_xsd::MixPorts& xMixPortsType : xMixPortsVec) {
310 for (const ap_xsd::MixPorts::MixPort& xMixPort : xMixPortsType.getMixPort()) {
311 audioPortVec.push_back(VALUE_OR_FATAL(convertMixPortToAidl(xMixPort, nextPortId)));
312 }
313 }
314 }
315 return audioPortVec;
316}
317
318ConversionResult<int32_t> getSinkPortId(const ap_xsd::Routes::Route& xRoute,
319 const std::unordered_map<std::string, int32_t>& portMap) {
320 auto portMapIter = portMap.find(xRoute.getSink());
321 if (portMapIter == portMap.end()) {
322 LOG(ERROR) << __func__ << " Review Audio Policy config: audio route"
323 << "has sink: " << xRoute.getSink()
324 << " which is neither a device port nor mix port.";
325 return unexpected(BAD_VALUE);
326 }
327 return portMapIter->second;
328}
329
330ConversionResult<std::vector<int32_t>> getSourcePortIds(
331 const ap_xsd::Routes::Route& xRoute,
332 const std::unordered_map<std::string, int32_t>& portMap) {
333 std::vector<int32_t> sourcePortIds;
334 for (const std::string& rawSource : ::android::base::Split(xRoute.getSources(), ",")) {
335 const std::string source = ::android::base::Trim(rawSource);
336 auto portMapIter = portMap.find(source);
337 if (portMapIter == portMap.end()) {
338 LOG(ERROR) << __func__ << " Review Audio Policy config: audio route"
339 << "has source \"" << source
340 << "\" which is neither a device port nor mix port.";
341 return unexpected(BAD_VALUE);
342 }
343 sourcePortIds.push_back(portMapIter->second);
344 }
345 return sourcePortIds;
346}
347
348ConversionResult<AudioRoute> convertRouteToAidl(const ap_xsd::Routes::Route& xRoute,
349 const std::vector<AudioPort>& aidlAudioPorts) {
350 std::unordered_map<std::string, int32_t> portMap;
351 for (const AudioPort& port : aidlAudioPorts) {
352 portMap.insert({port.name, port.id});
353 }
354 return AudioRoute{.sourcePortIds = VALUE_OR_FATAL(getSourcePortIds(xRoute, portMap)),
355 .sinkPortId = VALUE_OR_FATAL(getSinkPortId(xRoute, portMap)),
356 .isExclusive = (xRoute.getType() == ap_xsd::MixType::mux)};
357}
358
359ConversionResult<std::vector<AudioRoute>> convertRoutesInModuleToAidl(
360 const ap_xsd::Modules::Module& xModuleConfig,
361 const std::vector<AudioPort>& aidlAudioPorts) {
362 std::vector<AudioRoute> audioRouteVec;
363 std::vector<ap_xsd::Routes> xRoutesVec = xModuleConfig.getRoutes();
364 if (!xRoutesVec.empty()) {
365 /*
366 * xRoutesVec likely only contains one element; that is, it's
367 * likely that all ap_xsd::Routes::MixPort types that we need to convert
368 * are inside of xRoutesVec[0].
369 */
370 audioRouteVec.reserve(xRoutesVec[0].getRoute().size());
371 for (const ap_xsd::Routes& xRoutesType : xRoutesVec) {
372 for (const ap_xsd::Routes::Route& xRoute : xRoutesType.getRoute()) {
373 audioRouteVec.push_back(VALUE_OR_FATAL(convertRouteToAidl(xRoute, aidlAudioPorts)));
374 }
375 }
376 }
377 return audioRouteVec;
378}
379
380ConversionResult<std::unique_ptr<Module::Configuration>> convertModuleConfigToAidl(
381 const ap_xsd::Modules::Module& xModuleConfig) {
382 auto result = std::make_unique<Module::Configuration>();
383 auto& aidlModuleConfig = *result;
384 std::vector<AudioPort> devicePorts = VALUE_OR_FATAL(
385 convertDevicePortsInModuleToAidl(xModuleConfig, aidlModuleConfig.nextPortId));
386
387 // The XML config does not specify the default input device.
388 // Assign the first attached input device as the default.
389 for (auto& port : devicePorts) {
390 if (port.flags.getTag() != AudioIoFlags::input) continue;
391 auto& deviceExt = port.ext.get<AudioPortExt::device>();
392 if (!deviceExt.device.type.connection.empty()) continue;
393 deviceExt.flags |= 1 << AudioPortDeviceExt::FLAG_INDEX_DEFAULT_DEVICE;
394 break;
395 }
396
397 std::vector<AudioPort> mixPorts = VALUE_OR_FATAL(
398 convertMixPortsInModuleToAidl(xModuleConfig, aidlModuleConfig.nextPortId));
399 aidlModuleConfig.ports.reserve(devicePorts.size() + mixPorts.size());
400 aidlModuleConfig.ports.insert(aidlModuleConfig.ports.end(), devicePorts.begin(),
401 devicePorts.end());
402 aidlModuleConfig.ports.insert(aidlModuleConfig.ports.end(), mixPorts.begin(), mixPorts.end());
403
404 aidlModuleConfig.routes =
405 VALUE_OR_FATAL(convertRoutesInModuleToAidl(xModuleConfig, aidlModuleConfig.ports));
406 return result;
407}
408
409ConversionResult<AudioHalCapCriterion> convertCapCriterionToAidl(
410 const eng_xsd::CriterionType& xsdcCriterion) {
411 AudioHalCapCriterion aidlCapCriterion;
412 aidlCapCriterion.name = xsdcCriterion.getName();
413 aidlCapCriterion.criterionTypeName = xsdcCriterion.getType();
414 aidlCapCriterion.defaultLiteralValue = xsdcCriterion.get_default();
415 return aidlCapCriterion;
416}
417
418ConversionResult<std::string> convertCriterionTypeValueToAidl(
419 const eng_xsd::ValueType& xsdcCriterionTypeValue) {
420 return xsdcCriterionTypeValue.getLiteral();
421}
422
423ConversionResult<AudioHalCapCriterionType> convertCapCriterionTypeToAidl(
424 const eng_xsd::CriterionTypeType& xsdcCriterionType) {
425 AudioHalCapCriterionType aidlCapCriterionType;
426 aidlCapCriterionType.name = xsdcCriterionType.getName();
427 aidlCapCriterionType.isInclusive = !(static_cast<bool>(xsdcCriterionType.getType()));
428 aidlCapCriterionType.values = VALUE_OR_RETURN(
429 (convertWrappedCollectionToAidl<eng_xsd::ValuesType, eng_xsd::ValueType, std::string>(
430 xsdcCriterionType.getValues(), &eng_xsd::ValuesType::getValue,
431 &convertCriterionTypeValueToAidl)));
432 return aidlCapCriterionType;
433}
434
435ConversionResult<AudioHalVolumeCurve::CurvePoint> convertCurvePointToAidl(
436 const std::string& xsdcCurvePoint) {
437 AudioHalVolumeCurve::CurvePoint aidlCurvePoint{};
438 if ((sscanf(xsdcCurvePoint.c_str(), "%" SCNd8 ",%d", &aidlCurvePoint.index,
439 &aidlCurvePoint.attenuationMb) != 2) ||
440 (aidlCurvePoint.index < AudioHalVolumeCurve::CurvePoint::MIN_INDEX) ||
441 (aidlCurvePoint.index > AudioHalVolumeCurve::CurvePoint::MAX_INDEX)) {
442 LOG(ERROR) << __func__ << " Review Audio Policy config: volume curve point:"
443 << "\"" << xsdcCurvePoint << "\" is invalid";
444 return unexpected(BAD_VALUE);
445 }
446 return aidlCurvePoint;
447}
448} // namespace aidl::android::hardware::audio::core::internal