1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <stdio.h>
18 #include <string.h>
19 #include <algorithm>
20 
21 #define LOG_TAG "HidlUtils"
22 #include <log/log.h>
23 
24 #include PATH(APM_XSD_ENUMS_H_FILENAME)
25 #include <common/all-versions/HidlSupport.h>
26 #include <common/all-versions/VersionUtils.h>
27 
28 #include "HidlUtils.h"
29 
30 namespace android {
31 namespace hardware {
32 namespace audio {
33 namespace common {
34 namespace COMMON_TYPES_CPP_VERSION {
35 namespace implementation {
36 
37 namespace xsd {
38 using namespace ::android::audio::policy::configuration::CPP_VERSION;
39 }
40 
41 #define CONVERT_CHECKED(expr, result)                   \
42     if (status_t status = (expr); status != NO_ERROR) { \
43         result = status;                                \
44     }
45 
audioIndexChannelMaskFromHal(audio_channel_mask_t halChannelMask,AudioChannelMask * channelMask)46 status_t HidlUtils::audioIndexChannelMaskFromHal(audio_channel_mask_t halChannelMask,
47                                                  AudioChannelMask* channelMask) {
48     *channelMask = audio_channel_index_mask_to_string(halChannelMask);
49     if (!channelMask->empty() && !xsd::isUnknownAudioChannelMask(*channelMask)) {
50         return NO_ERROR;
51     }
52     ALOGE("Unknown index channel mask value 0x%X", halChannelMask);
53     *channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_NONE);
54     return BAD_VALUE;
55 }
56 
audioInputChannelMaskFromHal(audio_channel_mask_t halChannelMask,AudioChannelMask * channelMask)57 status_t HidlUtils::audioInputChannelMaskFromHal(audio_channel_mask_t halChannelMask,
58                                                  AudioChannelMask* channelMask) {
59     *channelMask = audio_channel_in_mask_to_string(halChannelMask);
60     if (!channelMask->empty() && !xsd::isUnknownAudioChannelMask(*channelMask)) {
61         return NO_ERROR;
62     }
63     ALOGE("Unknown input channel mask value 0x%X", halChannelMask);
64     *channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_NONE);
65     return BAD_VALUE;
66 }
67 
audioOutputChannelMaskFromHal(audio_channel_mask_t halChannelMask,AudioChannelMask * channelMask)68 status_t HidlUtils::audioOutputChannelMaskFromHal(audio_channel_mask_t halChannelMask,
69                                                   AudioChannelMask* channelMask) {
70     *channelMask = audio_channel_out_mask_to_string(halChannelMask);
71     if (!channelMask->empty() && !xsd::isUnknownAudioChannelMask(*channelMask)) {
72         return NO_ERROR;
73     }
74     ALOGE("Unknown output channel mask value 0x%X", halChannelMask);
75     *channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_NONE);
76     return BAD_VALUE;
77 }
78 
audioChannelMaskFromHal(audio_channel_mask_t halChannelMask,bool isInput,AudioChannelMask * channelMask)79 status_t HidlUtils::audioChannelMaskFromHal(audio_channel_mask_t halChannelMask, bool isInput,
80                                             AudioChannelMask* channelMask) {
81     if (halChannelMask != AUDIO_CHANNEL_NONE) {
82         if (audio_channel_mask_is_valid(halChannelMask)) {
83             switch (audio_channel_mask_get_representation(halChannelMask)) {
84                 case AUDIO_CHANNEL_REPRESENTATION_POSITION:
85                     return isInput ? audioInputChannelMaskFromHal(halChannelMask, channelMask)
86                                    : audioOutputChannelMaskFromHal(halChannelMask, channelMask);
87                 case AUDIO_CHANNEL_REPRESENTATION_INDEX:
88                     // Index masks do not have direction.
89                     return audioIndexChannelMaskFromHal(halChannelMask, channelMask);
90                     // no default
91             }
92         }
93         *channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_NONE);
94         return BAD_VALUE;
95     }
96     *channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_NONE);
97     return NO_ERROR;
98 }
99 
audioChannelMasksFromHal(const std::vector<std::string> & halChannelMasks,hidl_vec<AudioChannelMask> * channelMasks)100 status_t HidlUtils::audioChannelMasksFromHal(const std::vector<std::string>& halChannelMasks,
101                                              hidl_vec<AudioChannelMask>* channelMasks) {
102     hidl_vec<AudioChannelMask> tempChannelMasks;
103     tempChannelMasks.resize(halChannelMasks.size());
104     size_t tempPos = 0;
105     for (const auto& halChannelMask : halChannelMasks) {
106         if (!halChannelMask.empty() && !xsd::isUnknownAudioChannelMask(halChannelMask)) {
107             tempChannelMasks[tempPos++] = halChannelMask;
108         }
109     }
110     if (tempPos == tempChannelMasks.size()) {
111         *channelMasks = std::move(tempChannelMasks);
112     } else {
113         *channelMasks = hidl_vec<AudioChannelMask>(tempChannelMasks.begin(),
114                                                    tempChannelMasks.begin() + tempPos);
115     }
116     return halChannelMasks.size() == channelMasks->size() ? NO_ERROR : BAD_VALUE;
117 }
118 
audioChannelMaskToHal(const AudioChannelMask & channelMask,audio_channel_mask_t * halChannelMask)119 status_t HidlUtils::audioChannelMaskToHal(const AudioChannelMask& channelMask,
120                                           audio_channel_mask_t* halChannelMask) {
121     if (!xsd::isUnknownAudioChannelMask(channelMask) &&
122         audio_channel_mask_from_string(channelMask.c_str(), halChannelMask)) {
123         return NO_ERROR;
124     }
125     ALOGE("Unknown channel mask \"%s\"", channelMask.c_str());
126     *halChannelMask = AUDIO_CHANNEL_NONE;
127     return BAD_VALUE;
128 }
129 
audioConfigBaseFromHal(const audio_config_base_t & halConfigBase,bool isInput,AudioConfigBase * configBase)130 status_t HidlUtils::audioConfigBaseFromHal(const audio_config_base_t& halConfigBase, bool isInput,
131                                            AudioConfigBase* configBase) {
132     status_t result = NO_ERROR;
133     configBase->sampleRateHz = halConfigBase.sample_rate;
134     CONVERT_CHECKED(
135             audioChannelMaskFromHal(halConfigBase.channel_mask, isInput, &configBase->channelMask),
136             result);
137     CONVERT_CHECKED(audioFormatFromHal(halConfigBase.format, &configBase->format), result);
138     return result;
139 }
140 
audioConfigBaseToHal(const AudioConfigBase & configBase,audio_config_base_t * halConfigBase)141 status_t HidlUtils::audioConfigBaseToHal(const AudioConfigBase& configBase,
142                                          audio_config_base_t* halConfigBase) {
143     status_t result = NO_ERROR;
144     halConfigBase->sample_rate = configBase.sampleRateHz;
145     CONVERT_CHECKED(audioChannelMaskToHal(configBase.channelMask, &halConfigBase->channel_mask),
146                     result);
147     CONVERT_CHECKED(audioFormatToHal(configBase.format, &halConfigBase->format), result);
148     return result;
149 }
150 
audioConfigBaseOptionalFromHal(const audio_config_base_t & halConfigBase,bool isInput,bool formatSpecified,bool sampleRateSpecified,bool channelMaskSpecified,AudioConfigBaseOptional * configBase)151 status_t HidlUtils::audioConfigBaseOptionalFromHal(const audio_config_base_t& halConfigBase,
152                                                    bool isInput, bool formatSpecified,
153                                                    bool sampleRateSpecified,
154                                                    bool channelMaskSpecified,
155                                                    AudioConfigBaseOptional* configBase) {
156     status_t result = NO_ERROR;
157     if (formatSpecified) {
158         AudioFormat value;
159         CONVERT_CHECKED(audioFormatFromHal(halConfigBase.format, &value), result);
160         configBase->format.value(std::move(value));
161     } else {
162         configBase->format.unspecified({});
163     }
164     if (sampleRateSpecified) {
165         configBase->sampleRateHz.value(halConfigBase.sample_rate);
166     } else {
167         configBase->sampleRateHz.unspecified({});
168     }
169     if (channelMaskSpecified) {
170         AudioChannelMask value;
171         CONVERT_CHECKED(audioChannelMaskFromHal(halConfigBase.channel_mask, isInput, &value),
172                         result);
173         configBase->channelMask.value(std::move(value));
174     }
175     return result;
176 }
177 
audioConfigBaseOptionalToHal(const AudioConfigBaseOptional & configBase,audio_config_base_t * halConfigBase,bool * formatSpecified,bool * sampleRateSpecified,bool * channelMaskSpecified)178 status_t HidlUtils::audioConfigBaseOptionalToHal(const AudioConfigBaseOptional& configBase,
179                                                  audio_config_base_t* halConfigBase,
180                                                  bool* formatSpecified, bool* sampleRateSpecified,
181                                                  bool* channelMaskSpecified) {
182     status_t result = NO_ERROR;
183     *formatSpecified = configBase.format.getDiscriminator() ==
184                        AudioConfigBaseOptional::Format::hidl_discriminator::value;
185     if (*formatSpecified) {
186         CONVERT_CHECKED(audioFormatToHal(configBase.format.value(), &halConfigBase->format),
187                         result);
188     }
189     *sampleRateSpecified = configBase.sampleRateHz.getDiscriminator() ==
190                            AudioConfigBaseOptional::SampleRate::hidl_discriminator::value;
191     if (*sampleRateSpecified) {
192         halConfigBase->sample_rate = configBase.sampleRateHz.value();
193     }
194     *channelMaskSpecified = configBase.channelMask.getDiscriminator() ==
195                             AudioConfigBaseOptional::ChannelMask::hidl_discriminator::value;
196     if (*channelMaskSpecified) {
197         CONVERT_CHECKED(
198                 audioChannelMaskToHal(configBase.channelMask.value(), &halConfigBase->channel_mask),
199                 result);
200     }
201     return result;
202 }
203 
audioContentTypeFromHal(const audio_content_type_t halContentType,AudioContentType * contentType)204 status_t HidlUtils::audioContentTypeFromHal(const audio_content_type_t halContentType,
205                                             AudioContentType* contentType) {
206     *contentType = audio_content_type_to_string(halContentType);
207     if (!contentType->empty() && !xsd::isUnknownAudioContentType(*contentType)) {
208         return NO_ERROR;
209     }
210     ALOGE("Unknown audio content type value 0x%X", halContentType);
211     *contentType = toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_UNKNOWN);
212     return BAD_VALUE;
213 }
214 
audioContentTypeToHal(const AudioContentType & contentType,audio_content_type_t * halContentType)215 status_t HidlUtils::audioContentTypeToHal(const AudioContentType& contentType,
216                                           audio_content_type_t* halContentType) {
217     if (!xsd::isUnknownAudioContentType(contentType) &&
218         audio_content_type_from_string(contentType.c_str(), halContentType)) {
219         return NO_ERROR;
220     }
221     ALOGE("Unknown audio content type \"%s\"", contentType.c_str());
222     *halContentType = AUDIO_CONTENT_TYPE_UNKNOWN;
223     return BAD_VALUE;
224 }
225 
audioDeviceTypeFromHal(audio_devices_t halDevice,AudioDevice * device)226 status_t HidlUtils::audioDeviceTypeFromHal(audio_devices_t halDevice, AudioDevice* device) {
227     *device = audio_device_to_string(halDevice);
228     if (!device->empty() && !xsd::isUnknownAudioDevice(*device)) {
229         return NO_ERROR;
230     }
231     ALOGE("Unknown audio device value 0x%X", halDevice);
232     *device = toString(xsd::AudioDevice::AUDIO_DEVICE_NONE);
233     return BAD_VALUE;
234 }
235 
audioDeviceTypeToHal(const AudioDevice & device,audio_devices_t * halDevice)236 status_t HidlUtils::audioDeviceTypeToHal(const AudioDevice& device, audio_devices_t* halDevice) {
237     if (!xsd::isUnknownAudioDevice(device) && audio_device_from_string(device.c_str(), halDevice)) {
238         return NO_ERROR;
239     }
240     ALOGE("Unknown audio device \"%s\"", device.c_str());
241     *halDevice = AUDIO_DEVICE_NONE;
242     return BAD_VALUE;
243 }
244 
audioFormatFromHal(audio_format_t halFormat,AudioFormat * format)245 status_t HidlUtils::audioFormatFromHal(audio_format_t halFormat, AudioFormat* format) {
246     *format = audio_format_to_string(halFormat);
247     if (!format->empty() && !xsd::isUnknownAudioFormat(*format)) {
248         return NO_ERROR;
249     }
250     ALOGE("Unknown audio format value 0x%X", halFormat);
251     return BAD_VALUE;
252 }
253 
audioFormatsFromHal(const std::vector<std::string> & halFormats,hidl_vec<AudioFormat> * formats)254 status_t HidlUtils::audioFormatsFromHal(const std::vector<std::string>& halFormats,
255                                         hidl_vec<AudioFormat>* formats) {
256     hidl_vec<AudioFormat> tempFormats;
257     tempFormats.resize(halFormats.size());
258     size_t tempPos = 0;
259     for (const auto& halFormat : halFormats) {
260         if (!halFormat.empty() && !xsd::isUnknownAudioFormat(halFormat)) {
261             tempFormats[tempPos++] = halFormat;
262         }
263     }
264     if (tempPos == tempFormats.size()) {
265         *formats = std::move(tempFormats);
266     } else {
267         *formats = hidl_vec<AudioFormat>(tempFormats.begin(), tempFormats.begin() + tempPos);
268     }
269     return halFormats.size() == formats->size() ? NO_ERROR : BAD_VALUE;
270 }
271 
audioFormatToHal(const AudioFormat & format,audio_format_t * halFormat)272 status_t HidlUtils::audioFormatToHal(const AudioFormat& format, audio_format_t* halFormat) {
273     if (!xsd::isUnknownAudioFormat(format) && audio_format_from_string(format.c_str(), halFormat)) {
274         return NO_ERROR;
275     }
276     ALOGE("Unknown audio format \"%s\"", format.c_str());
277     *halFormat = AUDIO_FORMAT_DEFAULT;
278     return BAD_VALUE;
279 }
280 
audioGainModeMaskFromHal(audio_gain_mode_t halGainModeMask,hidl_vec<AudioGainMode> * gainModeMask)281 status_t HidlUtils::audioGainModeMaskFromHal(audio_gain_mode_t halGainModeMask,
282                                              hidl_vec<AudioGainMode>* gainModeMask) {
283     status_t status = NO_ERROR;
284     std::vector<AudioGainMode> result;
285     for (uint32_t bit = 0; halGainModeMask != 0 && bit < sizeof(audio_gain_mode_t) * 8; ++bit) {
286         audio_gain_mode_t flag = static_cast<audio_gain_mode_t>(1u << bit);
287         if ((flag & halGainModeMask) == flag) {
288             AudioGainMode flagStr = audio_gain_mode_to_string(flag);
289             if (!flagStr.empty() && !xsd::isUnknownAudioGainMode(flagStr)) {
290                 result.push_back(flagStr);
291             } else {
292                 ALOGE("Unknown audio gain mode value 0x%X", flag);
293                 status = BAD_VALUE;
294             }
295             halGainModeMask = static_cast<audio_gain_mode_t>(halGainModeMask & ~flag);
296         }
297     }
298     *gainModeMask = result;
299     return status;
300 }
301 
audioGainModeMaskToHal(const hidl_vec<AudioGainMode> & gainModeMask,audio_gain_mode_t * halGainModeMask)302 status_t HidlUtils::audioGainModeMaskToHal(const hidl_vec<AudioGainMode>& gainModeMask,
303                                            audio_gain_mode_t* halGainModeMask) {
304     status_t status = NO_ERROR;
305     *halGainModeMask = {};
306     for (const auto& gainMode : gainModeMask) {
307         audio_gain_mode_t halGainMode;
308         if (!xsd::isUnknownAudioGainMode(gainMode) &&
309             audio_gain_mode_from_string(gainMode.c_str(), &halGainMode)) {
310             *halGainModeMask = static_cast<audio_gain_mode_t>(*halGainModeMask | halGainMode);
311         } else {
312             ALOGE("Unknown audio gain mode \"%s\"", gainMode.c_str());
313             status = BAD_VALUE;
314         }
315     }
316     return status;
317 }
318 
audioSourceFromHal(audio_source_t halSource,AudioSource * source)319 status_t HidlUtils::audioSourceFromHal(audio_source_t halSource, AudioSource* source) {
320     *source = audio_source_to_string(halSource);
321     if (!source->empty() && !xsd::isUnknownAudioSource(*source)) {
322         return NO_ERROR;
323     }
324     ALOGE("Unknown audio source value 0x%X", halSource);
325     *source = toString(xsd::AudioSource::AUDIO_SOURCE_DEFAULT);
326     return BAD_VALUE;
327 }
328 
audioSourceToHal(const AudioSource & source,audio_source_t * halSource)329 status_t HidlUtils::audioSourceToHal(const AudioSource& source, audio_source_t* halSource) {
330     if (!xsd::isUnknownAudioSource(source) && audio_source_from_string(source.c_str(), halSource)) {
331         return NO_ERROR;
332     }
333     ALOGE("Unknown audio source \"%s\"", source.c_str());
334     *halSource = AUDIO_SOURCE_DEFAULT;
335     return BAD_VALUE;
336 }
337 
338 // The "default" value of audio_stream_type_t is represented by an empty string.
audioStreamTypeFromHal(audio_stream_type_t halStreamType,AudioStreamType * streamType)339 status_t HidlUtils::audioStreamTypeFromHal(audio_stream_type_t halStreamType,
340                                            AudioStreamType* streamType) {
341     if (halStreamType != AUDIO_STREAM_DEFAULT) {
342         *streamType = audio_stream_type_to_string(halStreamType);
343         if (!streamType->empty() && !xsd::isUnknownAudioStreamType(*streamType)) {
344             return NO_ERROR;
345         }
346         ALOGE("Unknown audio stream type value 0x%X", halStreamType);
347         return BAD_VALUE;
348     } else {
349         *streamType = "";
350         return NO_ERROR;
351     }
352 }
353 
audioStreamTypeToHal(const AudioStreamType & streamType,audio_stream_type_t * halStreamType)354 status_t HidlUtils::audioStreamTypeToHal(const AudioStreamType& streamType,
355                                          audio_stream_type_t* halStreamType) {
356     if (!streamType.empty()) {
357         if (!xsd::isUnknownAudioStreamType(streamType) &&
358             audio_stream_type_from_string(streamType.c_str(), halStreamType)) {
359             return NO_ERROR;
360         }
361         ALOGE("Unknown audio stream type \"%s\"", streamType.c_str());
362         return BAD_VALUE;
363     } else {
364         *halStreamType = AUDIO_STREAM_DEFAULT;
365         return NO_ERROR;
366     }
367 }
368 
audioConfigFromHal(const audio_config_t & halConfig,bool isInput,AudioConfig * config)369 status_t HidlUtils::audioConfigFromHal(const audio_config_t& halConfig, bool isInput,
370                                        AudioConfig* config) {
371     status_t result = NO_ERROR;
372     audio_config_base_t halConfigBase = {halConfig.sample_rate, halConfig.channel_mask,
373                                          halConfig.format};
374     CONVERT_CHECKED(audioConfigBaseFromHal(halConfigBase, isInput, &config->base), result);
375     if (halConfig.offload_info.sample_rate != 0) {
376         config->offloadInfo.info({});
377         CONVERT_CHECKED(
378                 audioOffloadInfoFromHal(halConfig.offload_info, &config->offloadInfo.info()),
379                 result);
380     }
381     config->frameCount = halConfig.frame_count;
382     return result;
383 }
384 
audioConfigToHal(const AudioConfig & config,audio_config_t * halConfig)385 status_t HidlUtils::audioConfigToHal(const AudioConfig& config, audio_config_t* halConfig) {
386     status_t result = NO_ERROR;
387     *halConfig = AUDIO_CONFIG_INITIALIZER;
388     audio_config_base_t halConfigBase = AUDIO_CONFIG_BASE_INITIALIZER;
389     CONVERT_CHECKED(audioConfigBaseToHal(config.base, &halConfigBase), result);
390     halConfig->sample_rate = halConfigBase.sample_rate;
391     halConfig->channel_mask = halConfigBase.channel_mask;
392     halConfig->format = halConfigBase.format;
393     if (config.offloadInfo.getDiscriminator() ==
394         AudioConfig::OffloadInfo::hidl_discriminator::info) {
395         CONVERT_CHECKED(audioOffloadInfoToHal(config.offloadInfo.info(), &halConfig->offload_info),
396                         result);
397     }
398     halConfig->frame_count = config.frameCount;
399     return result;
400 }
401 
audioGainConfigFromHal(const struct audio_gain_config & halConfig,bool isInput,AudioGainConfig * config)402 status_t HidlUtils::audioGainConfigFromHal(const struct audio_gain_config& halConfig, bool isInput,
403                                            AudioGainConfig* config) {
404     status_t result = NO_ERROR;
405     config->index = halConfig.index;
406     CONVERT_CHECKED(audioGainModeMaskFromHal(halConfig.mode, &config->mode), result);
407     CONVERT_CHECKED(audioChannelMaskFromHal(halConfig.channel_mask, isInput, &config->channelMask),
408                     result);
409     if (halConfig.mode & AUDIO_GAIN_MODE_JOINT) {
410         config->values.resize(1);
411         config->values[0] = halConfig.values[0];
412     }
413     if (halConfig.mode & (AUDIO_GAIN_MODE_CHANNELS | AUDIO_GAIN_MODE_RAMP)) {
414         config->values.resize(__builtin_popcount(halConfig.channel_mask));
415         for (size_t i = 0; i < config->values.size(); ++i) {
416             config->values[i] = halConfig.values[i];
417         }
418     }
419     config->rampDurationMs = halConfig.ramp_duration_ms;
420     return result;
421 }
422 
audioGainConfigToHal(const AudioGainConfig & config,struct audio_gain_config * halConfig)423 status_t HidlUtils::audioGainConfigToHal(const AudioGainConfig& config,
424                                          struct audio_gain_config* halConfig) {
425     status_t result = NO_ERROR;
426     halConfig->index = config.index;
427     CONVERT_CHECKED(audioGainModeMaskToHal(config.mode, &halConfig->mode), result);
428     CONVERT_CHECKED(audioChannelMaskToHal(config.channelMask, &halConfig->channel_mask), result);
429     memset(halConfig->values, 0, sizeof(halConfig->values));
430     if (halConfig->mode & AUDIO_GAIN_MODE_JOINT) {
431         if (config.values.size() > 0) {
432             halConfig->values[0] = config.values[0];
433         } else {
434             ALOGE("Empty values vector in AudioGainConfig");
435             result = BAD_VALUE;
436         }
437     }
438     if (halConfig->mode & (AUDIO_GAIN_MODE_CHANNELS | AUDIO_GAIN_MODE_RAMP)) {
439         size_t channelCount = __builtin_popcount(halConfig->channel_mask);
440         size_t valuesCount = config.values.size();
441         if (channelCount != valuesCount) {
442             ALOGE("Wrong number of values in AudioGainConfig, expected: %zu, found: %zu",
443                   channelCount, valuesCount);
444             result = BAD_VALUE;
445             if (channelCount < valuesCount) {
446                 valuesCount = channelCount;
447             }
448         }
449         for (size_t i = 0; i < valuesCount; ++i) {
450             halConfig->values[i] = config.values[i];
451         }
452     }
453     halConfig->ramp_duration_ms = config.rampDurationMs;
454     return result;
455 }
456 
audioGainFromHal(const struct audio_gain & halGain,bool isInput,AudioGain * gain)457 status_t HidlUtils::audioGainFromHal(const struct audio_gain& halGain, bool isInput,
458                                      AudioGain* gain) {
459     status_t result = NO_ERROR;
460     CONVERT_CHECKED(audioGainModeMaskFromHal(halGain.mode, &gain->mode), result);
461     CONVERT_CHECKED(audioChannelMaskFromHal(halGain.channel_mask, isInput, &gain->channelMask),
462                     result);
463     gain->minValue = halGain.min_value;
464     gain->maxValue = halGain.max_value;
465     gain->defaultValue = halGain.default_value;
466     gain->stepValue = halGain.step_value;
467     gain->minRampMs = halGain.min_ramp_ms;
468     gain->maxRampMs = halGain.max_ramp_ms;
469     return result;
470 }
471 
audioGainToHal(const AudioGain & gain,struct audio_gain * halGain)472 status_t HidlUtils::audioGainToHal(const AudioGain& gain, struct audio_gain* halGain) {
473     status_t result = NO_ERROR;
474     CONVERT_CHECKED(audioGainModeMaskToHal(gain.mode, &halGain->mode), result);
475     CONVERT_CHECKED(audioChannelMaskToHal(gain.channelMask, &halGain->channel_mask), result);
476     halGain->min_value = gain.minValue;
477     halGain->max_value = gain.maxValue;
478     halGain->default_value = gain.defaultValue;
479     halGain->step_value = gain.stepValue;
480     halGain->min_ramp_ms = gain.minRampMs;
481     halGain->max_ramp_ms = gain.maxRampMs;
482     return result;
483 }
484 
audioUsageFromHal(audio_usage_t halUsage,AudioUsage * usage)485 status_t HidlUtils::audioUsageFromHal(audio_usage_t halUsage, AudioUsage* usage) {
486     if (halUsage == AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST ||
487         halUsage == AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT ||
488 #if MAJOR_VERSION == 7 && MINOR_VERSION == 1
489         halUsage == AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED) {
490 #else
491         halUsage == AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED ||
492         halUsage == AUDIO_USAGE_NOTIFICATION_EVENT) {
493 #endif
494         halUsage = AUDIO_USAGE_NOTIFICATION;
495     }
496     *usage = audio_usage_to_string(halUsage);
497     if (!usage->empty() && !xsd::isUnknownAudioUsage(*usage)) {
498         return NO_ERROR;
499     }
500     ALOGE("Unknown audio usage %d", halUsage);
501     *usage = toString(xsd::AudioUsage::AUDIO_USAGE_UNKNOWN);
502     return BAD_VALUE;
503 }
504 
505 status_t HidlUtils::audioUsageToHal(const AudioUsage& usage, audio_usage_t* halUsage) {
506     if (!xsd::isUnknownAudioUsage(usage) && audio_usage_from_string(usage.c_str(), halUsage)) {
507         return NO_ERROR;
508     }
509     ALOGE("Unknown audio usage \"%s\"", usage.c_str());
510     *halUsage = AUDIO_USAGE_UNKNOWN;
511     return BAD_VALUE;
512 }
513 
514 status_t HidlUtils::audioOffloadInfoFromHal(const audio_offload_info_t& halOffload,
515                                             AudioOffloadInfo* offload) {
516     status_t result = NO_ERROR;
517     audio_config_base_t halConfigBase = {halOffload.sample_rate, halOffload.channel_mask,
518                                          halOffload.format};
519     CONVERT_CHECKED(audioConfigBaseFromHal(halConfigBase, false /*isInput*/, &offload->base),
520                     result);
521     CONVERT_CHECKED(audioStreamTypeFromHal(halOffload.stream_type, &offload->streamType), result);
522     offload->bitRatePerSecond = halOffload.bit_rate;
523     offload->durationMicroseconds = halOffload.duration_us;
524     offload->hasVideo = halOffload.has_video;
525     offload->isStreaming = halOffload.is_streaming;
526     offload->bitWidth = halOffload.bit_width;
527     offload->bufferSize = halOffload.offload_buffer_size;
528     CONVERT_CHECKED(audioUsageFromHal(halOffload.usage, &offload->usage), result);
529     if (halOffload.version >= AUDIO_OFFLOAD_INFO_VERSION_0_2) {
530         offload->encapsulationMode =
531                 static_cast<AudioEncapsulationMode>(halOffload.encapsulation_mode);
532         offload->contentId = halOffload.content_id;
533         offload->syncId = halOffload.sync_id;
534     } else {
535         offload->encapsulationMode = AudioEncapsulationMode::NONE;
536         offload->contentId = 0;
537         offload->syncId = 0;
538     }
539     return result;
540 }
541 
542 status_t HidlUtils::audioOffloadInfoToHal(const AudioOffloadInfo& offload,
543                                           audio_offload_info_t* halOffload) {
544     status_t result = NO_ERROR;
545     *halOffload = AUDIO_INFO_INITIALIZER;
546     audio_config_base_t halConfigBase = AUDIO_CONFIG_BASE_INITIALIZER;
547     CONVERT_CHECKED(audioConfigBaseToHal(offload.base, &halConfigBase), result);
548     halOffload->sample_rate = halConfigBase.sample_rate;
549     halOffload->channel_mask = halConfigBase.channel_mask;
550     halOffload->format = halConfigBase.format;
551     CONVERT_CHECKED(audioStreamTypeToHal(offload.streamType, &halOffload->stream_type), result);
552     halOffload->bit_rate = offload.bitRatePerSecond;
553     halOffload->duration_us = offload.durationMicroseconds;
554     halOffload->has_video = offload.hasVideo;
555     halOffload->is_streaming = offload.isStreaming;
556     halOffload->bit_width = offload.bitWidth;
557     halOffload->offload_buffer_size = offload.bufferSize;
558     CONVERT_CHECKED(audioUsageToHal(offload.usage, &halOffload->usage), result);
559     halOffload->encapsulation_mode =
560             static_cast<audio_encapsulation_mode_t>(offload.encapsulationMode);
561     halOffload->content_id = offload.contentId;
562     halOffload->sync_id = offload.syncId;
563     return result;
564 }
565 
566 status_t HidlUtils::audioPortConfigFromHal(const struct audio_port_config& halConfig,
567                                            AudioPortConfig* config) {
568     status_t result = NO_ERROR;
569     bool isInput = false;
570     config->id = halConfig.id;
571     CONVERT_CHECKED(audioPortExtendedInfoFromHal(halConfig.role, halConfig.type,
572                                                  halConfig.ext.device, halConfig.ext.mix,
573                                                  halConfig.ext.session, &config->ext, &isInput),
574                     result);
575     if (audio_port_config_has_input_direction(&halConfig) != isInput) {
576         ALOGE("Inconsistent port config direction data, is input: %d (hal) != %d (converter)",
577               audio_port_config_has_input_direction(&halConfig), isInput);
578         result = BAD_VALUE;
579     }
580     audio_config_base_t halConfigBase = {halConfig.sample_rate, halConfig.channel_mask,
581                                          halConfig.format};
582     CONVERT_CHECKED(
583             audioConfigBaseOptionalFromHal(
584                     halConfigBase, isInput, halConfig.config_mask & AUDIO_PORT_CONFIG_FORMAT,
585                     halConfig.config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE,
586                     halConfig.config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK, &config->base),
587             result);
588     if (halConfig.config_mask & AUDIO_PORT_CONFIG_GAIN) {
589         config->gain.config({});
590         CONVERT_CHECKED(audioGainConfigFromHal(halConfig.gain, isInput, &config->gain.config()),
591                         result);
592     } else {
593         config->gain.unspecified({});
594     }
595     return result;
596 }
597 
598 status_t HidlUtils::audioPortConfigToHal(const AudioPortConfig& config,
599                                          struct audio_port_config* halConfig) {
600     status_t result = NO_ERROR;
601     memset(halConfig, 0, sizeof(audio_port_config));
602     halConfig->id = config.id;
603     halConfig->config_mask = 0;
604     audio_config_base_t halConfigBase = AUDIO_CONFIG_BASE_INITIALIZER;
605     bool formatSpecified = false, sRateSpecified = false, channelMaskSpecified = false;
606     CONVERT_CHECKED(audioConfigBaseOptionalToHal(config.base, &halConfigBase, &formatSpecified,
607                                                  &sRateSpecified, &channelMaskSpecified),
608                     result);
609     if (sRateSpecified) {
610         halConfig->config_mask |= AUDIO_PORT_CONFIG_SAMPLE_RATE;
611         halConfig->sample_rate = halConfigBase.sample_rate;
612     }
613     if (channelMaskSpecified) {
614         halConfig->config_mask |= AUDIO_PORT_CONFIG_CHANNEL_MASK;
615         halConfig->channel_mask = halConfigBase.channel_mask;
616     }
617     if (formatSpecified) {
618         halConfig->config_mask |= AUDIO_PORT_CONFIG_FORMAT;
619         halConfig->format = halConfigBase.format;
620     }
621     if (config.gain.getDiscriminator() ==
622         AudioPortConfig::OptionalGain::hidl_discriminator::config) {
623         halConfig->config_mask |= AUDIO_PORT_CONFIG_GAIN;
624         CONVERT_CHECKED(audioGainConfigToHal(config.gain.config(), &halConfig->gain), result);
625     }
626     CONVERT_CHECKED(audioPortExtendedInfoToHal(config.ext, &halConfig->role, &halConfig->type,
627                                                &halConfig->ext.device, &halConfig->ext.mix,
628                                                &halConfig->ext.session),
629                     result);
630     return result;
631 }
632 
633 status_t HidlUtils::audioPortExtendedInfoFromHal(
634         audio_port_role_t role, audio_port_type_t type,
635         const struct audio_port_config_device_ext& device,
636         const struct audio_port_config_mix_ext& mix,
637         const struct audio_port_config_session_ext& session, AudioPortExtendedInfo* ext,
638         bool* isInput) {
639     status_t result = NO_ERROR;
640     *isInput = false;
641     switch (type) {
642         case AUDIO_PORT_TYPE_NONE:
643             ext->unspecified({});
644             break;
645         case AUDIO_PORT_TYPE_DEVICE: {
646             *isInput = role == AUDIO_PORT_ROLE_SOURCE;
647             ext->device({});
648             CONVERT_CHECKED(deviceAddressFromHal(device.type, device.address, &ext->device()),
649                             result);
650             break;
651         }
652         case AUDIO_PORT_TYPE_MIX: {
653             *isInput = role == AUDIO_PORT_ROLE_SINK;
654             ext->mix({});
655             ext->mix().ioHandle = mix.handle;
656             if (role == AUDIO_PORT_ROLE_SOURCE) {
657                 ext->mix().useCase.stream({});
658                 CONVERT_CHECKED(
659                         audioStreamTypeFromHal(mix.usecase.stream, &ext->mix().useCase.stream()),
660                         result);
661             } else if (role == AUDIO_PORT_ROLE_SINK) {
662                 ext->mix().useCase.source({});
663                 CONVERT_CHECKED(
664                         audioSourceFromHal(mix.usecase.source, &ext->mix().useCase.source()),
665                         result);
666             }
667             break;
668         }
669         case AUDIO_PORT_TYPE_SESSION: {
670             ext->session(session.session);
671             break;
672         }
673     }
674     return result;
675 }
676 
677 status_t HidlUtils::audioPortExtendedInfoToHal(const AudioPortExtendedInfo& ext,
678                                                audio_port_role_t* role, audio_port_type_t* type,
679                                                struct audio_port_config_device_ext* device,
680                                                struct audio_port_config_mix_ext* mix,
681                                                struct audio_port_config_session_ext* session) {
682     status_t result = NO_ERROR;
683     switch (ext.getDiscriminator()) {
684         case AudioPortExtendedInfo::hidl_discriminator::unspecified:
685             *role = AUDIO_PORT_ROLE_NONE;
686             *type = AUDIO_PORT_TYPE_NONE;
687             break;
688         case AudioPortExtendedInfo::hidl_discriminator::device:
689             *role = xsd::isOutputDevice(ext.device().deviceType) ? AUDIO_PORT_ROLE_SINK
690                                                                  : AUDIO_PORT_ROLE_SOURCE;
691             *type = AUDIO_PORT_TYPE_DEVICE;
692             CONVERT_CHECKED(deviceAddressToHal(ext.device(), &device->type, device->address),
693                             result);
694             break;
695         case AudioPortExtendedInfo::hidl_discriminator::mix:
696             *type = AUDIO_PORT_TYPE_MIX;
697             switch (ext.mix().useCase.getDiscriminator()) {
698                 case AudioPortExtendedInfo::AudioPortMixExt::UseCase::hidl_discriminator::stream:
699                     *role = AUDIO_PORT_ROLE_SOURCE;
700                     CONVERT_CHECKED(
701                             audioStreamTypeToHal(ext.mix().useCase.stream(), &mix->usecase.stream),
702                             result);
703                     break;
704                 case AudioPortExtendedInfo::AudioPortMixExt::UseCase::hidl_discriminator::source:
705                     *role = AUDIO_PORT_ROLE_SINK;
706                     CONVERT_CHECKED(
707                             audioSourceToHal(ext.mix().useCase.source(), &mix->usecase.source),
708                             result);
709                     break;
710             }
711             mix->handle = ext.mix().ioHandle;
712             break;
713         case AudioPortExtendedInfo::hidl_discriminator::session:
714             *role = AUDIO_PORT_ROLE_NONE;
715             *type = AUDIO_PORT_TYPE_SESSION;
716             session->session = static_cast<audio_session_t>(ext.session());
717             break;
718     }
719     return result;
720 }
721 
722 status_t HidlUtils::encapsulationTypeFromHal(audio_encapsulation_type_t halEncapsulationType,
723                                              AudioEncapsulationType* encapsulationType) {
724     *encapsulationType = audio_encapsulation_type_to_string(halEncapsulationType);
725     if (!encapsulationType->empty() && !xsd::isUnknownAudioEncapsulationType(*encapsulationType)) {
726         return NO_ERROR;
727     }
728     ALOGE("Unknown audio encapsulation type value 0x%X", halEncapsulationType);
729     return BAD_VALUE;
730 }
731 
732 status_t HidlUtils::encapsulationTypeToHal(const AudioEncapsulationType& encapsulationType,
733                                            audio_encapsulation_type_t* halEncapsulationType) {
734     if (!xsd::isUnknownAudioEncapsulationType(encapsulationType) &&
735         audio_encapsulation_type_from_string(encapsulationType.c_str(), halEncapsulationType)) {
736         return NO_ERROR;
737     }
738     ALOGE("Unknown audio encapsulation type \"%s\"", encapsulationType.c_str());
739     *halEncapsulationType = AUDIO_ENCAPSULATION_TYPE_NONE;
740     return BAD_VALUE;
741 }
742 
743 status_t HidlUtils::audioPortFromHal(const struct audio_port& halPort, AudioPort* port) {
744     struct audio_port_v7 halPortV7 = {};
745     audio_populate_audio_port_v7(&halPort, &halPortV7);
746     return audioPortFromHal(halPortV7, port);
747 }
748 
749 status_t HidlUtils::audioPortToHal(const AudioPort& port, struct audio_port* halPort) {
750     status_t result = NO_ERROR;
751     struct audio_port_v7 halPortV7 = {};
752     CONVERT_CHECKED(audioPortToHal(port, &halPortV7), result);
753     if (!audio_populate_audio_port(&halPortV7, halPort)) {
754         result = BAD_VALUE;
755     }
756     return result;
757 }
758 
759 status_t HidlUtils::audioPortFromHal(const struct audio_port_v7& halPort, AudioPort* port) {
760     status_t result = NO_ERROR;
761     bool isInput = false;
762     port->id = halPort.id;
763     port->name.setToExternal(halPort.name, strlen(halPort.name));
764     // HAL uses slightly different but convertible structures for the extended info in port
765     // and port config structures.
766     struct audio_port_config_device_ext halDevice = {};
767     struct audio_port_config_mix_ext halMix = {};
768     struct audio_port_config_session_ext halSession = {};
769     switch (halPort.type) {
770         case AUDIO_PORT_TYPE_NONE:
771             break;
772         case AUDIO_PORT_TYPE_DEVICE:
773             halDevice.type = halPort.ext.device.type;
774             memcpy(halDevice.address, halPort.ext.device.address, AUDIO_DEVICE_MAX_ADDRESS_LEN);
775             break;
776         case AUDIO_PORT_TYPE_MIX:
777             halMix.handle = halPort.ext.mix.handle;
778             break;
779         case AUDIO_PORT_TYPE_SESSION:
780             halSession.session = halPort.ext.session.session;
781             break;
782     }
783     CONVERT_CHECKED(audioPortExtendedInfoFromHal(halPort.role, halPort.type, halDevice, halMix,
784                                                  halSession, &port->ext, &isInput),
785                     result);
786     CONVERT_CHECKED(audioTransportsFromHal(halPort, isInput, &port->transports), result);
787     port->gains.resize(halPort.num_gains);
788     for (size_t i = 0; i < halPort.num_gains; ++i) {
789         CONVERT_CHECKED(audioGainFromHal(halPort.gains[i], isInput, &port->gains[i]), result);
790     }
791     CONVERT_CHECKED(audioPortConfigFromHal(halPort.active_config, &port->activeConfig), result);
792     return result;
793 }
794 
795 status_t HidlUtils::audioPortToHal(const AudioPort& port, struct audio_port_v7* halPort) {
796     status_t result = NO_ERROR;
797     halPort->id = port.id;
798     strncpy(halPort->name, port.name.c_str(), AUDIO_PORT_MAX_NAME_LEN);
799     halPort->name[AUDIO_PORT_MAX_NAME_LEN - 1] = '\0';
800     if (port.name.size() >= AUDIO_PORT_MAX_NAME_LEN) {
801         ALOGE("HIDL Audio Port name is too long: %zu", port.name.size());
802         result = BAD_VALUE;
803     }
804     CONVERT_CHECKED(audioTransportsToHal(port.transports, halPort), result);
805     halPort->num_gains = port.gains.size();
806     if (halPort->num_gains > AUDIO_PORT_MAX_GAINS) {
807         ALOGE("HIDL Audio Port has too many gains: %u", halPort->num_gains);
808         halPort->num_gains = AUDIO_PORT_MAX_GAINS;
809         result = BAD_VALUE;
810     }
811     for (size_t i = 0; i < halPort->num_gains; ++i) {
812         CONVERT_CHECKED(audioGainToHal(port.gains[i], &halPort->gains[i]), result);
813     }
814     // HAL uses slightly different but convertible structures for the extended info in port
815     // and port config structures.
816     struct audio_port_config_device_ext halDevice = {};
817     struct audio_port_config_mix_ext halMix = {};
818     struct audio_port_config_session_ext halSession = {};
819     CONVERT_CHECKED(audioPortExtendedInfoToHal(port.ext, &halPort->role, &halPort->type, &halDevice,
820                                                &halMix, &halSession),
821                     result);
822     switch (halPort->type) {
823         case AUDIO_PORT_TYPE_NONE:
824             break;
825         case AUDIO_PORT_TYPE_DEVICE:
826             halPort->ext.device.type = halDevice.type;
827             memcpy(halPort->ext.device.address, halDevice.address, AUDIO_DEVICE_MAX_ADDRESS_LEN);
828             break;
829         case AUDIO_PORT_TYPE_MIX:
830             halPort->ext.mix.handle = halMix.handle;
831             break;
832         case AUDIO_PORT_TYPE_SESSION:
833             halPort->ext.session.session = halSession.session;
834             break;
835     }
836     CONVERT_CHECKED(audioPortConfigToHal(port.activeConfig, &halPort->active_config), result);
837     return result;
838 }
839 
840 status_t HidlUtils::audioTransportsFromHal(const struct audio_port_v7& halPort, bool isInput,
841                                            hidl_vec<AudioTransport>* transports) {
842     if (halPort.num_audio_profiles > AUDIO_PORT_MAX_AUDIO_PROFILES ||
843         halPort.num_extra_audio_descriptors > AUDIO_PORT_MAX_EXTRA_AUDIO_DESCRIPTORS) {
844         ALOGE("%s, too many audio profiles(%u) or extra audio descriptors(%u)", __func__,
845               halPort.num_audio_profiles, halPort.num_extra_audio_descriptors);
846         return BAD_VALUE;
847     }
848     status_t result = NO_ERROR;
849     transports->resize(halPort.num_audio_profiles + halPort.num_extra_audio_descriptors);
850     size_t idx = 0;
851     for (size_t i = 0; i < halPort.num_audio_profiles; ++i) {
852         auto& transport = (*transports)[idx++];
853         transport.audioCapability.profile({});
854         CONVERT_CHECKED(audioProfileFromHal(halPort.audio_profiles[i], isInput,
855                                             &transport.audioCapability.profile()),
856                         result);
857         CONVERT_CHECKED(encapsulationTypeFromHal(halPort.audio_profiles[i].encapsulation_type,
858                                                  &transport.encapsulationType),
859                         result);
860     }
861     for (size_t i = 0; i < halPort.num_extra_audio_descriptors; ++i) {
862         switch (halPort.extra_audio_descriptors[i].standard) {
863             case AUDIO_STANDARD_EDID: {
864                 const struct audio_extra_audio_descriptor* extraAudioDescriptor =
865                         &halPort.extra_audio_descriptors[i];
866                 if (extraAudioDescriptor->descriptor_length <= EXTRA_AUDIO_DESCRIPTOR_SIZE) {
867                     auto& transport = (*transports)[idx++];
868                     transport.audioCapability.edid(
869                             hidl_vec<uint8_t>(extraAudioDescriptor->descriptor,
870                                               extraAudioDescriptor->descriptor +
871                                                       extraAudioDescriptor->descriptor_length));
872                     CONVERT_CHECKED(
873                             encapsulationTypeFromHal(extraAudioDescriptor->encapsulation_type,
874                                                      &transport.encapsulationType),
875                             result);
876                 } else {
877                     ALOGE("%s, invalid descriptor length %u", __func__,
878                           extraAudioDescriptor->descriptor_length);
879                     result = BAD_VALUE;
880                 }
881             } break;
882             case AUDIO_STANDARD_NONE:
883             default:
884                 ALOGE("%s, invalid standard %u", __func__,
885                       halPort.extra_audio_descriptors[i].standard);
886                 result = BAD_VALUE;
887                 break;
888         }
889     }
890     return result;
891 }
892 
893 status_t HidlUtils::audioTransportsToHal(const hidl_vec<AudioTransport>& transports,
894                                          struct audio_port_v7* halPort) {
895     status_t result = NO_ERROR;
896     halPort->num_audio_profiles = 0;
897     halPort->num_extra_audio_descriptors = 0;
898     for (const auto& transport : transports) {
899         switch (transport.audioCapability.getDiscriminator()) {
900             case AudioTransport::AudioCapability::hidl_discriminator::profile:
901                 if (halPort->num_audio_profiles >= AUDIO_PORT_MAX_AUDIO_PROFILES) {
902                     ALOGE("%s, too many audio profiles", __func__);
903                     result = BAD_VALUE;
904                     break;
905                 }
906                 CONVERT_CHECKED(
907                         audioProfileToHal(transport.audioCapability.profile(),
908                                           &halPort->audio_profiles[halPort->num_audio_profiles]),
909                         result);
910                 CONVERT_CHECKED(encapsulationTypeToHal(
911                                         transport.encapsulationType,
912                                         &halPort->audio_profiles[halPort->num_audio_profiles++]
913                                                  .encapsulation_type),
914                                 result);
915                 break;
916             case AudioTransport::AudioCapability::hidl_discriminator::edid:
917                 if (halPort->num_extra_audio_descriptors >=
918                     AUDIO_PORT_MAX_EXTRA_AUDIO_DESCRIPTORS) {
919                     ALOGE("%s, too many extra audio descriptors", __func__);
920                     result = BAD_VALUE;
921                     break;
922                 }
923                 if (transport.audioCapability.edid().size() > EXTRA_AUDIO_DESCRIPTOR_SIZE) {
924                     ALOGE("%s, wrong edid size %zu", __func__,
925                           transport.audioCapability.edid().size());
926                     result = BAD_VALUE;
927                     break;
928                 }
929                 struct audio_extra_audio_descriptor* extraAudioDescriptor =
930                         &halPort->extra_audio_descriptors[halPort->num_extra_audio_descriptors++];
931                 extraAudioDescriptor->standard = AUDIO_STANDARD_EDID;
932                 extraAudioDescriptor->descriptor_length = transport.audioCapability.edid().size();
933                 memcpy(extraAudioDescriptor->descriptor, transport.audioCapability.edid().data(),
934                        transport.audioCapability.edid().size() * sizeof(uint8_t));
935 
936                 CONVERT_CHECKED(encapsulationTypeToHal(transport.encapsulationType,
937                                                        &extraAudioDescriptor->encapsulation_type),
938                                 result);
939                 break;
940         }
941     }
942     return result;
943 }
944 
945 status_t HidlUtils::audioProfileFromHal(const struct audio_profile& halProfile, bool isInput,
946                                         AudioProfile* profile) {
947     status_t result = NO_ERROR;
948     CONVERT_CHECKED(audioFormatFromHal(halProfile.format, &profile->format), result);
949     profile->sampleRates.resize(halProfile.num_sample_rates);
950     for (size_t i = 0; i < halProfile.num_sample_rates; ++i) {
951         profile->sampleRates[i] = halProfile.sample_rates[i];
952     }
953     profile->channelMasks.resize(halProfile.num_channel_masks);
954     for (size_t i = 0; i < halProfile.num_channel_masks; ++i) {
955         CONVERT_CHECKED(audioChannelMaskFromHal(halProfile.channel_masks[i], isInput,
956                                                 &profile->channelMasks[i]),
957                         result);
958     }
959     return result;
960 }
961 
962 status_t HidlUtils::audioProfileToHal(const AudioProfile& profile,
963                                       struct audio_profile* halProfile) {
964     status_t result = NO_ERROR;
965     CONVERT_CHECKED(audioFormatToHal(profile.format, &halProfile->format), result);
966     memset(halProfile->sample_rates, 0, sizeof(halProfile->sample_rates));
967     halProfile->num_sample_rates = profile.sampleRates.size();
968     if (halProfile->num_sample_rates > AUDIO_PORT_MAX_SAMPLING_RATES) {
969         ALOGE("HIDL Audio profile has too many sample rates: %u", halProfile->num_sample_rates);
970         halProfile->num_sample_rates = AUDIO_PORT_MAX_SAMPLING_RATES;
971         result = BAD_VALUE;
972     }
973     for (size_t i = 0; i < halProfile->num_sample_rates; ++i) {
974         halProfile->sample_rates[i] = profile.sampleRates[i];
975     }
976     memset(halProfile->channel_masks, 0, sizeof(halProfile->channel_masks));
977     halProfile->num_channel_masks = profile.channelMasks.size();
978     if (halProfile->num_channel_masks > AUDIO_PORT_MAX_CHANNEL_MASKS) {
979         ALOGE("HIDL Audio profile has too many channel masks: %u", halProfile->num_channel_masks);
980         halProfile->num_channel_masks = AUDIO_PORT_MAX_CHANNEL_MASKS;
981         result = BAD_VALUE;
982     }
983     for (size_t i = 0; i < halProfile->num_channel_masks; ++i) {
984         CONVERT_CHECKED(
985                 audioChannelMaskToHal(profile.channelMasks[i], &halProfile->channel_masks[i]),
986                 status);
987     }
988     return result;
989 }
990 
991 status_t HidlUtils::audioTagsFromHal(const std::vector<std::string>& strTags,
992                                      hidl_vec<AudioTag>* tags) {
993     status_t result = NO_ERROR;
994     tags->resize(strTags.size());
995     size_t to = 0;
996     for (size_t from = 0; from < strTags.size(); ++from) {
997         const auto& tag = strTags[from];
998         if (xsd::isVendorExtension(tag)) {
999             (*tags)[to++] = tag;
1000         } else {
1001             ALOGE("Vendor extension tag is ill-formed: \"%s\"", tag.c_str());
1002             result = BAD_VALUE;
1003         }
1004     }
1005     if (to != strTags.size()) {
1006         tags->resize(to);
1007     }
1008     return result;
1009 }
1010 
1011 status_t HidlUtils::audioTagsToHal(const hidl_vec<AudioTag>& tags, char* halTags) {
1012     memset(halTags, 0, AUDIO_ATTRIBUTES_TAGS_MAX_SIZE);
1013     status_t result = NO_ERROR;
1014     std::ostringstream halTagsBuffer;
1015     bool hasValue = false;
1016     for (const auto& tag : tags) {
1017         if (hasValue) {
1018             halTagsBuffer << sAudioTagSeparator;
1019         }
1020         if (xsd::isVendorExtension(tag) && strchr(tag.c_str(), sAudioTagSeparator) == nullptr) {
1021             halTagsBuffer << tag;
1022             hasValue = true;
1023         } else {
1024             ALOGE("Vendor extension tag is ill-formed: \"%s\"", tag.c_str());
1025             result = BAD_VALUE;
1026         }
1027     }
1028     std::string fullHalTags{std::move(halTagsBuffer.str())};
1029     strncpy(halTags, fullHalTags.c_str(), AUDIO_ATTRIBUTES_TAGS_MAX_SIZE);
1030     CONVERT_CHECKED(fullHalTags.length() <= AUDIO_ATTRIBUTES_TAGS_MAX_SIZE ? NO_ERROR : BAD_VALUE,
1031                     result);
1032     return result;
1033 }
1034 
1035 hidl_vec<AudioTag> HidlUtils::filterOutNonVendorTags(const hidl_vec<AudioTag>& tags) {
1036     hidl_vec<AudioTag> result;
1037     result.resize(tags.size());
1038     size_t resultIdx = 0;
1039     for (const auto& tag : tags) {
1040         if (xsd::maybeVendorExtension(tag)) {
1041             result[resultIdx++] = tag;
1042         }
1043     }
1044     if (resultIdx != result.size()) {
1045         result.resize(resultIdx);
1046     }
1047     return result;
1048 }
1049 
1050 std::vector<std::string> HidlUtils::filterOutNonVendorTags(const std::vector<std::string>& tags) {
1051     std::vector<std::string> result;
1052     std::copy_if(tags.begin(), tags.end(), std::back_inserter(result), xsd::maybeVendorExtension);
1053     return result;
1054 }
1055 
1056 std::vector<std::string> HidlUtils::splitAudioTags(const char* halTags) {
1057     return utils::splitString(halTags, sAudioTagSeparator);
1058 }
1059 
1060 status_t HidlUtils::deviceAddressFromHal(audio_devices_t halDeviceType,
1061                                          const char* halDeviceAddress, DeviceAddress* device) {
1062     status_t result = NO_ERROR;
1063     CONVERT_CHECKED(audioDeviceTypeFromHal(halDeviceType, &device->deviceType), result);
1064     if (audio_is_a2dp_out_device(halDeviceType) || audio_is_a2dp_in_device(halDeviceType)) {
1065         device->address.mac({});
1066         if (halDeviceAddress != nullptr) {
1067             auto& mac = device->address.mac();
1068             int status = sscanf(halDeviceAddress, "%hhX:%hhX:%hhX:%hhX:%hhX:%hhX", &mac[0], &mac[1],
1069                                 &mac[2], &mac[3], &mac[4], &mac[5]);
1070             if (status != 6) {
1071                 ALOGE("BT A2DP device \"%s\" MAC address \"%s\" is invalid",
1072                       device->deviceType.c_str(), halDeviceAddress);
1073                 result = BAD_VALUE;
1074             }
1075         } else {
1076             ALOGE("BT A2DP device \"%s\" does not have a MAC address", halDeviceAddress);
1077             result = BAD_VALUE;
1078         }
1079     } else if (halDeviceType == AUDIO_DEVICE_OUT_IP || halDeviceType == AUDIO_DEVICE_IN_IP) {
1080         device->address.ipv4({});
1081         if (halDeviceAddress != nullptr) {
1082             auto& ipv4 = device->address.ipv4();
1083             int status = sscanf(halDeviceAddress, "%hhu.%hhu.%hhu.%hhu", &ipv4[0], &ipv4[1],
1084                                 &ipv4[2], &ipv4[3]);
1085             if (status != 4) {
1086                 ALOGE("IP device \"%s\" IPv4 address \"%s\" is invalid", device->deviceType.c_str(),
1087                       halDeviceAddress);
1088                 result = BAD_VALUE;
1089             }
1090         } else {
1091             ALOGE("IP device \"%s\" does not have an IPv4 address", device->deviceType.c_str());
1092             result = BAD_VALUE;
1093         }
1094     } else if (audio_is_usb_out_device(halDeviceType) || audio_is_usb_in_device(halDeviceType)) {
1095         device->address.alsa({});
1096         if (halDeviceAddress != nullptr) {
1097             auto& alsa = device->address.alsa();
1098             int status = sscanf(halDeviceAddress, "card=%d;device=%d", &alsa.card, &alsa.device);
1099             if (status != 2) {
1100                 ALOGE("USB device \"%s\" ALSA address \"%s\" is invalid",
1101                       device->deviceType.c_str(), halDeviceAddress);
1102                 result = BAD_VALUE;
1103             }
1104         } else {
1105             ALOGE("USB device \"%s\" does not have ALSA address", device->deviceType.c_str());
1106             result = BAD_VALUE;
1107         }
1108     } else {
1109         // Any other device type uses the 'id' field.
1110         device->address.id(halDeviceAddress != nullptr ? halDeviceAddress : "");
1111     }
1112     return result;
1113 }
1114 
1115 status_t HidlUtils::deviceAddressToHal(const DeviceAddress& device, audio_devices_t* halDeviceType,
1116                                        char* halDeviceAddress) {
1117     status_t result = NO_ERROR;
1118     CONVERT_CHECKED(audioDeviceTypeToHal(device.deviceType, halDeviceType), result);
1119     memset(halDeviceAddress, 0, AUDIO_DEVICE_MAX_ADDRESS_LEN);
1120     if (audio_is_a2dp_out_device(*halDeviceType) || audio_is_a2dp_in_device(*halDeviceType)) {
1121         if (device.address.getDiscriminator() == DeviceAddress::Address::hidl_discriminator::mac) {
1122             const auto& mac = device.address.mac();
1123             snprintf(halDeviceAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN,
1124                      "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4],
1125                      mac[5]);
1126         } else {
1127             ALOGE("BT A2DP device \"%s\" does not have MAC address set", device.deviceType.c_str());
1128             result = BAD_VALUE;
1129         }
1130     } else if (*halDeviceType == AUDIO_DEVICE_OUT_IP || *halDeviceType == AUDIO_DEVICE_IN_IP) {
1131         if (device.address.getDiscriminator() == DeviceAddress::Address::hidl_discriminator::ipv4) {
1132             const auto& ipv4 = device.address.ipv4();
1133             snprintf(halDeviceAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN, "%d.%d.%d.%d", ipv4[0],
1134                      ipv4[1], ipv4[2], ipv4[3]);
1135         } else {
1136             ALOGE("IP device \"%s\" does not have IPv4 address set", device.deviceType.c_str());
1137             result = BAD_VALUE;
1138         }
1139     } else if (audio_is_usb_out_device(*halDeviceType) || audio_is_usb_in_device(*halDeviceType)) {
1140         if (device.address.getDiscriminator() == DeviceAddress::Address::hidl_discriminator::alsa) {
1141             const auto& alsa = device.address.alsa();
1142             snprintf(halDeviceAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN, "card=%d;device=%d", alsa.card,
1143                      alsa.device);
1144         } else {
1145             ALOGE("USB device \"%s\" does not have ALSA address set", device.deviceType.c_str());
1146             result = BAD_VALUE;
1147         }
1148     } else {
1149         // Any other device type uses the 'id' field.
1150         if (device.address.getDiscriminator() == DeviceAddress::Address::hidl_discriminator::id) {
1151             snprintf(halDeviceAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN, "%s",
1152                      device.address.id().c_str());
1153         }
1154     }
1155     return result;
1156 }
1157 
1158 }  // namespace implementation
1159 }  // namespace COMMON_TYPES_CPP_VERSION
1160 }  // namespace common
1161 }  // namespace audio
1162 }  // namespace hardware
1163 }  // namespace android
1164