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 <android_audio_policy_configuration_V7_0-enums.h>
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 CPP_VERSION {
35 namespace implementation {
36 
37 namespace xsd {
38 using namespace ::android::audio::policy::configuration::V7_0;
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         halUsage == AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED ||
489         halUsage == AUDIO_USAGE_NOTIFICATION_EVENT) {
490         halUsage = AUDIO_USAGE_NOTIFICATION;
491     }
492     *usage = audio_usage_to_string(halUsage);
493     if (!usage->empty() && !xsd::isUnknownAudioUsage(*usage)) {
494         return NO_ERROR;
495     }
496     ALOGE("Unknown audio usage %d", halUsage);
497     *usage = toString(xsd::AudioUsage::AUDIO_USAGE_UNKNOWN);
498     return BAD_VALUE;
499 }
500 
audioUsageToHal(const AudioUsage & usage,audio_usage_t * halUsage)501 status_t HidlUtils::audioUsageToHal(const AudioUsage& usage, audio_usage_t* halUsage) {
502     if (!xsd::isUnknownAudioUsage(usage) && audio_usage_from_string(usage.c_str(), halUsage)) {
503         return NO_ERROR;
504     }
505     ALOGE("Unknown audio usage \"%s\"", usage.c_str());
506     *halUsage = AUDIO_USAGE_UNKNOWN;
507     return BAD_VALUE;
508 }
509 
audioOffloadInfoFromHal(const audio_offload_info_t & halOffload,AudioOffloadInfo * offload)510 status_t HidlUtils::audioOffloadInfoFromHal(const audio_offload_info_t& halOffload,
511                                             AudioOffloadInfo* offload) {
512     status_t result = NO_ERROR;
513     audio_config_base_t halConfigBase = {halOffload.sample_rate, halOffload.channel_mask,
514                                          halOffload.format};
515     CONVERT_CHECKED(audioConfigBaseFromHal(halConfigBase, false /*isInput*/, &offload->base),
516                     result);
517     CONVERT_CHECKED(audioStreamTypeFromHal(halOffload.stream_type, &offload->streamType), result);
518     offload->bitRatePerSecond = halOffload.bit_rate;
519     offload->durationMicroseconds = halOffload.duration_us;
520     offload->hasVideo = halOffload.has_video;
521     offload->isStreaming = halOffload.is_streaming;
522     offload->bitWidth = halOffload.bit_width;
523     offload->bufferSize = halOffload.offload_buffer_size;
524     CONVERT_CHECKED(audioUsageFromHal(halOffload.usage, &offload->usage), result);
525     if (halOffload.version >= AUDIO_OFFLOAD_INFO_VERSION_0_2) {
526         offload->encapsulationMode =
527                 static_cast<AudioEncapsulationMode>(halOffload.encapsulation_mode);
528         offload->contentId = halOffload.content_id;
529         offload->syncId = halOffload.sync_id;
530     } else {
531         offload->encapsulationMode = AudioEncapsulationMode::NONE;
532         offload->contentId = 0;
533         offload->syncId = 0;
534     }
535     return result;
536 }
537 
audioOffloadInfoToHal(const AudioOffloadInfo & offload,audio_offload_info_t * halOffload)538 status_t HidlUtils::audioOffloadInfoToHal(const AudioOffloadInfo& offload,
539                                           audio_offload_info_t* halOffload) {
540     status_t result = NO_ERROR;
541     *halOffload = AUDIO_INFO_INITIALIZER;
542     audio_config_base_t halConfigBase = AUDIO_CONFIG_BASE_INITIALIZER;
543     CONVERT_CHECKED(audioConfigBaseToHal(offload.base, &halConfigBase), result);
544     halOffload->sample_rate = halConfigBase.sample_rate;
545     halOffload->channel_mask = halConfigBase.channel_mask;
546     halOffload->format = halConfigBase.format;
547     CONVERT_CHECKED(audioStreamTypeToHal(offload.streamType, &halOffload->stream_type), result);
548     halOffload->bit_rate = offload.bitRatePerSecond;
549     halOffload->duration_us = offload.durationMicroseconds;
550     halOffload->has_video = offload.hasVideo;
551     halOffload->is_streaming = offload.isStreaming;
552     halOffload->bit_width = offload.bitWidth;
553     halOffload->offload_buffer_size = offload.bufferSize;
554     CONVERT_CHECKED(audioUsageToHal(offload.usage, &halOffload->usage), result);
555     halOffload->encapsulation_mode =
556             static_cast<audio_encapsulation_mode_t>(offload.encapsulationMode);
557     halOffload->content_id = offload.contentId;
558     halOffload->sync_id = offload.syncId;
559     return result;
560 }
561 
audioPortConfigFromHal(const struct audio_port_config & halConfig,AudioPortConfig * config)562 status_t HidlUtils::audioPortConfigFromHal(const struct audio_port_config& halConfig,
563                                            AudioPortConfig* config) {
564     status_t result = NO_ERROR;
565     bool isInput = false;
566     config->id = halConfig.id;
567     CONVERT_CHECKED(audioPortExtendedInfoFromHal(halConfig.role, halConfig.type,
568                                                  halConfig.ext.device, halConfig.ext.mix,
569                                                  halConfig.ext.session, &config->ext, &isInput),
570                     result);
571     if (audio_port_config_has_input_direction(&halConfig) != isInput) {
572         ALOGE("Inconsistent port config direction data, is input: %d (hal) != %d (converter)",
573               audio_port_config_has_input_direction(&halConfig), isInput);
574         result = BAD_VALUE;
575     }
576     audio_config_base_t halConfigBase = {halConfig.sample_rate, halConfig.channel_mask,
577                                          halConfig.format};
578     CONVERT_CHECKED(
579             audioConfigBaseOptionalFromHal(
580                     halConfigBase, isInput, halConfig.config_mask & AUDIO_PORT_CONFIG_FORMAT,
581                     halConfig.config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE,
582                     halConfig.config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK, &config->base),
583             result);
584     if (halConfig.config_mask & AUDIO_PORT_CONFIG_GAIN) {
585         config->gain.config({});
586         CONVERT_CHECKED(audioGainConfigFromHal(halConfig.gain, isInput, &config->gain.config()),
587                         result);
588     } else {
589         config->gain.unspecified({});
590     }
591     return result;
592 }
593 
audioPortConfigToHal(const AudioPortConfig & config,struct audio_port_config * halConfig)594 status_t HidlUtils::audioPortConfigToHal(const AudioPortConfig& config,
595                                          struct audio_port_config* halConfig) {
596     status_t result = NO_ERROR;
597     memset(halConfig, 0, sizeof(audio_port_config));
598     halConfig->id = config.id;
599     halConfig->config_mask = 0;
600     audio_config_base_t halConfigBase = AUDIO_CONFIG_BASE_INITIALIZER;
601     bool formatSpecified = false, sRateSpecified = false, channelMaskSpecified = false;
602     CONVERT_CHECKED(audioConfigBaseOptionalToHal(config.base, &halConfigBase, &formatSpecified,
603                                                  &sRateSpecified, &channelMaskSpecified),
604                     result);
605     if (sRateSpecified) {
606         halConfig->config_mask |= AUDIO_PORT_CONFIG_SAMPLE_RATE;
607         halConfig->sample_rate = halConfigBase.sample_rate;
608     }
609     if (channelMaskSpecified) {
610         halConfig->config_mask |= AUDIO_PORT_CONFIG_CHANNEL_MASK;
611         halConfig->channel_mask = halConfigBase.channel_mask;
612     }
613     if (formatSpecified) {
614         halConfig->config_mask |= AUDIO_PORT_CONFIG_FORMAT;
615         halConfig->format = halConfigBase.format;
616     }
617     if (config.gain.getDiscriminator() ==
618         AudioPortConfig::OptionalGain::hidl_discriminator::config) {
619         halConfig->config_mask |= AUDIO_PORT_CONFIG_GAIN;
620         CONVERT_CHECKED(audioGainConfigToHal(config.gain.config(), &halConfig->gain), result);
621     }
622     CONVERT_CHECKED(audioPortExtendedInfoToHal(config.ext, &halConfig->role, &halConfig->type,
623                                                &halConfig->ext.device, &halConfig->ext.mix,
624                                                &halConfig->ext.session),
625                     result);
626     return result;
627 }
628 
audioPortExtendedInfoFromHal(audio_port_role_t role,audio_port_type_t type,const struct audio_port_config_device_ext & device,const struct audio_port_config_mix_ext & mix,const struct audio_port_config_session_ext & session,AudioPortExtendedInfo * ext,bool * isInput)629 status_t HidlUtils::audioPortExtendedInfoFromHal(
630         audio_port_role_t role, audio_port_type_t type,
631         const struct audio_port_config_device_ext& device,
632         const struct audio_port_config_mix_ext& mix,
633         const struct audio_port_config_session_ext& session, AudioPortExtendedInfo* ext,
634         bool* isInput) {
635     status_t result = NO_ERROR;
636     *isInput = false;
637     switch (type) {
638         case AUDIO_PORT_TYPE_NONE:
639             ext->unspecified({});
640             break;
641         case AUDIO_PORT_TYPE_DEVICE: {
642             *isInput = role == AUDIO_PORT_ROLE_SOURCE;
643             ext->device({});
644             CONVERT_CHECKED(deviceAddressFromHal(device.type, device.address, &ext->device()),
645                             result);
646             break;
647         }
648         case AUDIO_PORT_TYPE_MIX: {
649             *isInput = role == AUDIO_PORT_ROLE_SINK;
650             ext->mix({});
651             ext->mix().ioHandle = mix.handle;
652             if (role == AUDIO_PORT_ROLE_SOURCE) {
653                 ext->mix().useCase.stream({});
654                 CONVERT_CHECKED(
655                         audioStreamTypeFromHal(mix.usecase.stream, &ext->mix().useCase.stream()),
656                         result);
657             } else if (role == AUDIO_PORT_ROLE_SINK) {
658                 ext->mix().useCase.source({});
659                 CONVERT_CHECKED(
660                         audioSourceFromHal(mix.usecase.source, &ext->mix().useCase.source()),
661                         result);
662             }
663             break;
664         }
665         case AUDIO_PORT_TYPE_SESSION: {
666             ext->session(session.session);
667             break;
668         }
669     }
670     return result;
671 }
672 
audioPortExtendedInfoToHal(const AudioPortExtendedInfo & ext,audio_port_role_t * role,audio_port_type_t * type,struct audio_port_config_device_ext * device,struct audio_port_config_mix_ext * mix,struct audio_port_config_session_ext * session)673 status_t HidlUtils::audioPortExtendedInfoToHal(const AudioPortExtendedInfo& ext,
674                                                audio_port_role_t* role, audio_port_type_t* type,
675                                                struct audio_port_config_device_ext* device,
676                                                struct audio_port_config_mix_ext* mix,
677                                                struct audio_port_config_session_ext* session) {
678     status_t result = NO_ERROR;
679     switch (ext.getDiscriminator()) {
680         case AudioPortExtendedInfo::hidl_discriminator::unspecified:
681             *role = AUDIO_PORT_ROLE_NONE;
682             *type = AUDIO_PORT_TYPE_NONE;
683             break;
684         case AudioPortExtendedInfo::hidl_discriminator::device:
685             *role = xsd::isOutputDevice(ext.device().deviceType) ? AUDIO_PORT_ROLE_SINK
686                                                                  : AUDIO_PORT_ROLE_SOURCE;
687             *type = AUDIO_PORT_TYPE_DEVICE;
688             CONVERT_CHECKED(deviceAddressToHal(ext.device(), &device->type, device->address),
689                             result);
690             break;
691         case AudioPortExtendedInfo::hidl_discriminator::mix:
692             *type = AUDIO_PORT_TYPE_MIX;
693             switch (ext.mix().useCase.getDiscriminator()) {
694                 case AudioPortExtendedInfo::AudioPortMixExt::UseCase::hidl_discriminator::stream:
695                     *role = AUDIO_PORT_ROLE_SOURCE;
696                     CONVERT_CHECKED(
697                             audioStreamTypeToHal(ext.mix().useCase.stream(), &mix->usecase.stream),
698                             result);
699                     break;
700                 case AudioPortExtendedInfo::AudioPortMixExt::UseCase::hidl_discriminator::source:
701                     *role = AUDIO_PORT_ROLE_SINK;
702                     CONVERT_CHECKED(
703                             audioSourceToHal(ext.mix().useCase.source(), &mix->usecase.source),
704                             result);
705                     break;
706             }
707             mix->handle = ext.mix().ioHandle;
708             break;
709         case AudioPortExtendedInfo::hidl_discriminator::session:
710             *role = AUDIO_PORT_ROLE_NONE;
711             *type = AUDIO_PORT_TYPE_SESSION;
712             session->session = static_cast<audio_session_t>(ext.session());
713             break;
714     }
715     return result;
716 }
717 
encapsulationTypeFromHal(audio_encapsulation_type_t halEncapsulationType,AudioEncapsulationType * encapsulationType)718 status_t HidlUtils::encapsulationTypeFromHal(audio_encapsulation_type_t halEncapsulationType,
719                                              AudioEncapsulationType* encapsulationType) {
720     *encapsulationType = audio_encapsulation_type_to_string(halEncapsulationType);
721     if (!encapsulationType->empty() && !xsd::isUnknownAudioEncapsulationType(*encapsulationType)) {
722         return NO_ERROR;
723     }
724     ALOGE("Unknown audio encapsulation type value 0x%X", halEncapsulationType);
725     return BAD_VALUE;
726 }
727 
encapsulationTypeToHal(const AudioEncapsulationType & encapsulationType,audio_encapsulation_type_t * halEncapsulationType)728 status_t HidlUtils::encapsulationTypeToHal(const AudioEncapsulationType& encapsulationType,
729                                            audio_encapsulation_type_t* halEncapsulationType) {
730     if (!xsd::isUnknownAudioEncapsulationType(encapsulationType) &&
731         audio_encapsulation_type_from_string(encapsulationType.c_str(), halEncapsulationType)) {
732         return NO_ERROR;
733     }
734     ALOGE("Unknown audio encapsulation type \"%s\"", encapsulationType.c_str());
735     *halEncapsulationType = AUDIO_ENCAPSULATION_TYPE_NONE;
736     return BAD_VALUE;
737 }
738 
audioPortFromHal(const struct audio_port & halPort,AudioPort * port)739 status_t HidlUtils::audioPortFromHal(const struct audio_port& halPort, AudioPort* port) {
740     struct audio_port_v7 halPortV7 = {};
741     audio_populate_audio_port_v7(&halPort, &halPortV7);
742     return audioPortFromHal(halPortV7, port);
743 }
744 
audioPortToHal(const AudioPort & port,struct audio_port * halPort)745 status_t HidlUtils::audioPortToHal(const AudioPort& port, struct audio_port* halPort) {
746     status_t result = NO_ERROR;
747     struct audio_port_v7 halPortV7 = {};
748     CONVERT_CHECKED(audioPortToHal(port, &halPortV7), result);
749     if (!audio_populate_audio_port(&halPortV7, halPort)) {
750         result = BAD_VALUE;
751     }
752     return result;
753 }
754 
audioPortFromHal(const struct audio_port_v7 & halPort,AudioPort * port)755 status_t HidlUtils::audioPortFromHal(const struct audio_port_v7& halPort, AudioPort* port) {
756     status_t result = NO_ERROR;
757     bool isInput = false;
758     port->id = halPort.id;
759     port->name.setToExternal(halPort.name, strlen(halPort.name));
760     // HAL uses slightly different but convertible structures for the extended info in port
761     // and port config structures.
762     struct audio_port_config_device_ext halDevice = {};
763     struct audio_port_config_mix_ext halMix = {};
764     struct audio_port_config_session_ext halSession = {};
765     switch (halPort.type) {
766         case AUDIO_PORT_TYPE_NONE:
767             break;
768         case AUDIO_PORT_TYPE_DEVICE:
769             halDevice.type = halPort.ext.device.type;
770             memcpy(halDevice.address, halPort.ext.device.address, AUDIO_DEVICE_MAX_ADDRESS_LEN);
771             break;
772         case AUDIO_PORT_TYPE_MIX:
773             halMix.handle = halPort.ext.mix.handle;
774             break;
775         case AUDIO_PORT_TYPE_SESSION:
776             halSession.session = halPort.ext.session.session;
777             break;
778     }
779     CONVERT_CHECKED(audioPortExtendedInfoFromHal(halPort.role, halPort.type, halDevice, halMix,
780                                                  halSession, &port->ext, &isInput),
781                     result);
782     CONVERT_CHECKED(audioTransportsFromHal(halPort, isInput, &port->transports), result);
783     port->gains.resize(halPort.num_gains);
784     for (size_t i = 0; i < halPort.num_gains; ++i) {
785         CONVERT_CHECKED(audioGainFromHal(halPort.gains[i], isInput, &port->gains[i]), result);
786     }
787     CONVERT_CHECKED(audioPortConfigFromHal(halPort.active_config, &port->activeConfig), result);
788     return result;
789 }
790 
audioPortToHal(const AudioPort & port,struct audio_port_v7 * halPort)791 status_t HidlUtils::audioPortToHal(const AudioPort& port, struct audio_port_v7* halPort) {
792     status_t result = NO_ERROR;
793     halPort->id = port.id;
794     strncpy(halPort->name, port.name.c_str(), AUDIO_PORT_MAX_NAME_LEN);
795     halPort->name[AUDIO_PORT_MAX_NAME_LEN - 1] = '\0';
796     if (port.name.size() >= AUDIO_PORT_MAX_NAME_LEN) {
797         ALOGE("HIDL Audio Port name is too long: %zu", port.name.size());
798         result = BAD_VALUE;
799     }
800     CONVERT_CHECKED(audioTransportsToHal(port.transports, halPort), result);
801     halPort->num_gains = port.gains.size();
802     if (halPort->num_gains > AUDIO_PORT_MAX_GAINS) {
803         ALOGE("HIDL Audio Port has too many gains: %u", halPort->num_gains);
804         halPort->num_gains = AUDIO_PORT_MAX_GAINS;
805         result = BAD_VALUE;
806     }
807     for (size_t i = 0; i < halPort->num_gains; ++i) {
808         CONVERT_CHECKED(audioGainToHal(port.gains[i], &halPort->gains[i]), result);
809     }
810     // HAL uses slightly different but convertible structures for the extended info in port
811     // and port config structures.
812     struct audio_port_config_device_ext halDevice = {};
813     struct audio_port_config_mix_ext halMix = {};
814     struct audio_port_config_session_ext halSession = {};
815     CONVERT_CHECKED(audioPortExtendedInfoToHal(port.ext, &halPort->role, &halPort->type, &halDevice,
816                                                &halMix, &halSession),
817                     result);
818     switch (halPort->type) {
819         case AUDIO_PORT_TYPE_NONE:
820             break;
821         case AUDIO_PORT_TYPE_DEVICE:
822             halPort->ext.device.type = halDevice.type;
823             memcpy(halPort->ext.device.address, halDevice.address, AUDIO_DEVICE_MAX_ADDRESS_LEN);
824             break;
825         case AUDIO_PORT_TYPE_MIX:
826             halPort->ext.mix.handle = halMix.handle;
827             break;
828         case AUDIO_PORT_TYPE_SESSION:
829             halPort->ext.session.session = halSession.session;
830             break;
831     }
832     CONVERT_CHECKED(audioPortConfigToHal(port.activeConfig, &halPort->active_config), result);
833     return result;
834 }
835 
audioTransportsFromHal(const struct audio_port_v7 & halPort,bool isInput,hidl_vec<AudioTransport> * transports)836 status_t HidlUtils::audioTransportsFromHal(const struct audio_port_v7& halPort, bool isInput,
837                                            hidl_vec<AudioTransport>* transports) {
838     if (halPort.num_audio_profiles > AUDIO_PORT_MAX_AUDIO_PROFILES ||
839         halPort.num_extra_audio_descriptors > AUDIO_PORT_MAX_EXTRA_AUDIO_DESCRIPTORS) {
840         ALOGE("%s, too many audio profiles(%u) or extra audio descriptors(%u)", __func__,
841               halPort.num_audio_profiles, halPort.num_extra_audio_descriptors);
842         return BAD_VALUE;
843     }
844     status_t result = NO_ERROR;
845     transports->resize(halPort.num_audio_profiles + halPort.num_extra_audio_descriptors);
846     size_t idx = 0;
847     for (size_t i = 0; i < halPort.num_audio_profiles; ++i) {
848         auto& transport = (*transports)[idx++];
849         transport.audioCapability.profile({});
850         CONVERT_CHECKED(audioProfileFromHal(halPort.audio_profiles[i], isInput,
851                                             &transport.audioCapability.profile()),
852                         result);
853         CONVERT_CHECKED(encapsulationTypeFromHal(halPort.audio_profiles[i].encapsulation_type,
854                                                  &transport.encapsulationType),
855                         result);
856     }
857     for (size_t i = 0; i < halPort.num_extra_audio_descriptors; ++i) {
858         switch (halPort.extra_audio_descriptors[i].standard) {
859             case AUDIO_STANDARD_EDID: {
860                 const struct audio_extra_audio_descriptor* extraAudioDescriptor =
861                         &halPort.extra_audio_descriptors[i];
862                 if (extraAudioDescriptor->descriptor_length <= EXTRA_AUDIO_DESCRIPTOR_SIZE) {
863                     auto& transport = (*transports)[idx++];
864                     transport.audioCapability.edid(
865                             hidl_vec<uint8_t>(extraAudioDescriptor->descriptor,
866                                               extraAudioDescriptor->descriptor +
867                                                       extraAudioDescriptor->descriptor_length));
868                     CONVERT_CHECKED(
869                             encapsulationTypeFromHal(extraAudioDescriptor->encapsulation_type,
870                                                      &transport.encapsulationType),
871                             result);
872                 } else {
873                     ALOGE("%s, invalid descriptor length %u", __func__,
874                           extraAudioDescriptor->descriptor_length);
875                     result = BAD_VALUE;
876                 }
877             } break;
878             case AUDIO_STANDARD_NONE:
879             default:
880                 ALOGE("%s, invalid standard %u", __func__,
881                       halPort.extra_audio_descriptors[i].standard);
882                 result = BAD_VALUE;
883                 break;
884         }
885     }
886     return result;
887 }
888 
audioTransportsToHal(const hidl_vec<AudioTransport> & transports,struct audio_port_v7 * halPort)889 status_t HidlUtils::audioTransportsToHal(const hidl_vec<AudioTransport>& transports,
890                                          struct audio_port_v7* halPort) {
891     status_t result = NO_ERROR;
892     halPort->num_audio_profiles = 0;
893     halPort->num_extra_audio_descriptors = 0;
894     for (const auto& transport : transports) {
895         switch (transport.audioCapability.getDiscriminator()) {
896             case AudioTransport::AudioCapability::hidl_discriminator::profile:
897                 if (halPort->num_audio_profiles > AUDIO_PORT_MAX_AUDIO_PROFILES) {
898                     ALOGE("%s, too many audio profiles", __func__);
899                     result = BAD_VALUE;
900                     break;
901                 }
902                 CONVERT_CHECKED(
903                         audioProfileToHal(transport.audioCapability.profile(),
904                                           &halPort->audio_profiles[halPort->num_audio_profiles]),
905                         result);
906                 CONVERT_CHECKED(encapsulationTypeToHal(
907                                         transport.encapsulationType,
908                                         &halPort->audio_profiles[halPort->num_audio_profiles++]
909                                                  .encapsulation_type),
910                                 result);
911                 break;
912             case AudioTransport::AudioCapability::hidl_discriminator::edid:
913                 if (halPort->num_extra_audio_descriptors > AUDIO_PORT_MAX_EXTRA_AUDIO_DESCRIPTORS) {
914                     ALOGE("%s, too many extra audio descriptors", __func__);
915                     result = BAD_VALUE;
916                     break;
917                 }
918                 if (transport.audioCapability.edid().size() > EXTRA_AUDIO_DESCRIPTOR_SIZE) {
919                     ALOGE("%s, wrong edid size %zu", __func__,
920                           transport.audioCapability.edid().size());
921                     result = BAD_VALUE;
922                     break;
923                 }
924                 struct audio_extra_audio_descriptor* extraAudioDescriptor =
925                         &halPort->extra_audio_descriptors[halPort->num_extra_audio_descriptors++];
926                 extraAudioDescriptor->standard = AUDIO_STANDARD_EDID;
927                 extraAudioDescriptor->descriptor_length = transport.audioCapability.edid().size();
928                 memcpy(extraAudioDescriptor->descriptor, transport.audioCapability.edid().data(),
929                        transport.audioCapability.edid().size() * sizeof(uint8_t));
930 
931                 CONVERT_CHECKED(encapsulationTypeToHal(transport.encapsulationType,
932                                                        &extraAudioDescriptor->encapsulation_type),
933                                 result);
934                 break;
935         }
936     }
937     return result;
938 }
939 
audioProfileFromHal(const struct audio_profile & halProfile,bool isInput,AudioProfile * profile)940 status_t HidlUtils::audioProfileFromHal(const struct audio_profile& halProfile, bool isInput,
941                                         AudioProfile* profile) {
942     status_t result = NO_ERROR;
943     CONVERT_CHECKED(audioFormatFromHal(halProfile.format, &profile->format), result);
944     profile->sampleRates.resize(halProfile.num_sample_rates);
945     for (size_t i = 0; i < halProfile.num_sample_rates; ++i) {
946         profile->sampleRates[i] = halProfile.sample_rates[i];
947     }
948     profile->channelMasks.resize(halProfile.num_channel_masks);
949     for (size_t i = 0; i < halProfile.num_channel_masks; ++i) {
950         CONVERT_CHECKED(audioChannelMaskFromHal(halProfile.channel_masks[i], isInput,
951                                                 &profile->channelMasks[i]),
952                         result);
953     }
954     return result;
955 }
956 
audioProfileToHal(const AudioProfile & profile,struct audio_profile * halProfile)957 status_t HidlUtils::audioProfileToHal(const AudioProfile& profile,
958                                       struct audio_profile* halProfile) {
959     status_t result = NO_ERROR;
960     CONVERT_CHECKED(audioFormatToHal(profile.format, &halProfile->format), result);
961     memset(halProfile->sample_rates, 0, sizeof(halProfile->sample_rates));
962     halProfile->num_sample_rates = profile.sampleRates.size();
963     if (halProfile->num_sample_rates > AUDIO_PORT_MAX_SAMPLING_RATES) {
964         ALOGE("HIDL Audio profile has too many sample rates: %u", halProfile->num_sample_rates);
965         halProfile->num_sample_rates = AUDIO_PORT_MAX_SAMPLING_RATES;
966         result = BAD_VALUE;
967     }
968     for (size_t i = 0; i < halProfile->num_sample_rates; ++i) {
969         halProfile->sample_rates[i] = profile.sampleRates[i];
970     }
971     memset(halProfile->channel_masks, 0, sizeof(halProfile->channel_masks));
972     halProfile->num_channel_masks = profile.channelMasks.size();
973     if (halProfile->num_channel_masks > AUDIO_PORT_MAX_CHANNEL_MASKS) {
974         ALOGE("HIDL Audio profile has too many channel masks: %u", halProfile->num_channel_masks);
975         halProfile->num_channel_masks = AUDIO_PORT_MAX_CHANNEL_MASKS;
976         result = BAD_VALUE;
977     }
978     for (size_t i = 0; i < halProfile->num_channel_masks; ++i) {
979         CONVERT_CHECKED(
980                 audioChannelMaskToHal(profile.channelMasks[i], &halProfile->channel_masks[i]),
981                 status);
982     }
983     return result;
984 }
985 
audioTagsFromHal(const std::vector<std::string> & strTags,hidl_vec<AudioTag> * tags)986 status_t HidlUtils::audioTagsFromHal(const std::vector<std::string>& strTags,
987                                      hidl_vec<AudioTag>* tags) {
988     status_t result = NO_ERROR;
989     tags->resize(strTags.size());
990     size_t to = 0;
991     for (size_t from = 0; from < strTags.size(); ++from) {
992         const auto& tag = strTags[from];
993         if (xsd::isVendorExtension(tag)) {
994             (*tags)[to++] = tag;
995         } else {
996             ALOGE("Vendor extension tag is ill-formed: \"%s\"", tag.c_str());
997             result = BAD_VALUE;
998         }
999     }
1000     if (to != strTags.size()) {
1001         tags->resize(to);
1002     }
1003     return result;
1004 }
1005 
audioTagsToHal(const hidl_vec<AudioTag> & tags,char * halTags)1006 status_t HidlUtils::audioTagsToHal(const hidl_vec<AudioTag>& tags, char* halTags) {
1007     memset(halTags, 0, AUDIO_ATTRIBUTES_TAGS_MAX_SIZE);
1008     status_t result = NO_ERROR;
1009     std::ostringstream halTagsBuffer;
1010     bool hasValue = false;
1011     for (const auto& tag : tags) {
1012         if (hasValue) {
1013             halTagsBuffer << sAudioTagSeparator;
1014         }
1015         if (xsd::isVendorExtension(tag) && strchr(tag.c_str(), sAudioTagSeparator) == nullptr) {
1016             halTagsBuffer << tag;
1017             hasValue = true;
1018         } else {
1019             ALOGE("Vendor extension tag is ill-formed: \"%s\"", tag.c_str());
1020             result = BAD_VALUE;
1021         }
1022     }
1023     std::string fullHalTags{std::move(halTagsBuffer.str())};
1024     strncpy(halTags, fullHalTags.c_str(), AUDIO_ATTRIBUTES_TAGS_MAX_SIZE);
1025     CONVERT_CHECKED(fullHalTags.length() <= AUDIO_ATTRIBUTES_TAGS_MAX_SIZE ? NO_ERROR : BAD_VALUE,
1026                     result);
1027     return result;
1028 }
1029 
filterOutNonVendorTags(const hidl_vec<AudioTag> & tags)1030 hidl_vec<AudioTag> HidlUtils::filterOutNonVendorTags(const hidl_vec<AudioTag>& tags) {
1031     hidl_vec<AudioTag> result;
1032     result.resize(tags.size());
1033     size_t resultIdx = 0;
1034     for (const auto& tag : tags) {
1035         if (xsd::maybeVendorExtension(tag)) {
1036             result[resultIdx++] = tag;
1037         }
1038     }
1039     if (resultIdx != result.size()) {
1040         result.resize(resultIdx);
1041     }
1042     return result;
1043 }
1044 
filterOutNonVendorTags(const std::vector<std::string> & tags)1045 std::vector<std::string> HidlUtils::filterOutNonVendorTags(const std::vector<std::string>& tags) {
1046     std::vector<std::string> result;
1047     std::copy_if(tags.begin(), tags.end(), std::back_inserter(result), xsd::maybeVendorExtension);
1048     return result;
1049 }
1050 
splitAudioTags(const char * halTags)1051 std::vector<std::string> HidlUtils::splitAudioTags(const char* halTags) {
1052     return utils::splitString(halTags, sAudioTagSeparator);
1053 }
1054 
deviceAddressFromHal(audio_devices_t halDeviceType,const char * halDeviceAddress,DeviceAddress * device)1055 status_t HidlUtils::deviceAddressFromHal(audio_devices_t halDeviceType,
1056                                          const char* halDeviceAddress, DeviceAddress* device) {
1057     status_t result = NO_ERROR;
1058     CONVERT_CHECKED(audioDeviceTypeFromHal(halDeviceType, &device->deviceType), result);
1059     if (audio_is_a2dp_out_device(halDeviceType) || audio_is_a2dp_in_device(halDeviceType)) {
1060         device->address.mac({});
1061         if (halDeviceAddress != nullptr) {
1062             auto& mac = device->address.mac();
1063             int status = sscanf(halDeviceAddress, "%hhX:%hhX:%hhX:%hhX:%hhX:%hhX", &mac[0], &mac[1],
1064                                 &mac[2], &mac[3], &mac[4], &mac[5]);
1065             if (status != 6) {
1066                 ALOGE("BT A2DP device \"%s\" MAC address \"%s\" is invalid",
1067                       device->deviceType.c_str(), halDeviceAddress);
1068                 result = BAD_VALUE;
1069             }
1070         } else {
1071             ALOGE("BT A2DP device \"%s\" does not have a MAC address", halDeviceAddress);
1072             result = BAD_VALUE;
1073         }
1074     } else if (halDeviceType == AUDIO_DEVICE_OUT_IP || halDeviceType == AUDIO_DEVICE_IN_IP) {
1075         device->address.ipv4({});
1076         if (halDeviceAddress != nullptr) {
1077             auto& ipv4 = device->address.ipv4();
1078             int status = sscanf(halDeviceAddress, "%hhu.%hhu.%hhu.%hhu", &ipv4[0], &ipv4[1],
1079                                 &ipv4[2], &ipv4[3]);
1080             if (status != 4) {
1081                 ALOGE("IP device \"%s\" IPv4 address \"%s\" is invalid", device->deviceType.c_str(),
1082                       halDeviceAddress);
1083                 result = BAD_VALUE;
1084             }
1085         } else {
1086             ALOGE("IP device \"%s\" does not have an IPv4 address", device->deviceType.c_str());
1087             result = BAD_VALUE;
1088         }
1089     } else if (audio_is_usb_out_device(halDeviceType) || audio_is_usb_in_device(halDeviceType)) {
1090         device->address.alsa({});
1091         if (halDeviceAddress != nullptr) {
1092             auto& alsa = device->address.alsa();
1093             int status = sscanf(halDeviceAddress, "card=%d;device=%d", &alsa.card, &alsa.device);
1094             if (status != 2) {
1095                 ALOGE("USB device \"%s\" ALSA address \"%s\" is invalid",
1096                       device->deviceType.c_str(), halDeviceAddress);
1097                 result = BAD_VALUE;
1098             }
1099         } else {
1100             ALOGE("USB device \"%s\" does not have ALSA address", device->deviceType.c_str());
1101             result = BAD_VALUE;
1102         }
1103     } else {
1104         // Any other device type uses the 'id' field.
1105         device->address.id(halDeviceAddress != nullptr ? halDeviceAddress : "");
1106     }
1107     return result;
1108 }
1109 
deviceAddressToHal(const DeviceAddress & device,audio_devices_t * halDeviceType,char * halDeviceAddress)1110 status_t HidlUtils::deviceAddressToHal(const DeviceAddress& device, audio_devices_t* halDeviceType,
1111                                        char* halDeviceAddress) {
1112     status_t result = NO_ERROR;
1113     CONVERT_CHECKED(audioDeviceTypeToHal(device.deviceType, halDeviceType), result);
1114     memset(halDeviceAddress, 0, AUDIO_DEVICE_MAX_ADDRESS_LEN);
1115     if (audio_is_a2dp_out_device(*halDeviceType) || audio_is_a2dp_in_device(*halDeviceType)) {
1116         if (device.address.getDiscriminator() == DeviceAddress::Address::hidl_discriminator::mac) {
1117             const auto& mac = device.address.mac();
1118             snprintf(halDeviceAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN,
1119                      "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4],
1120                      mac[5]);
1121         } else {
1122             ALOGE("BT A2DP device \"%s\" does not have MAC address set", device.deviceType.c_str());
1123             result = BAD_VALUE;
1124         }
1125     } else if (*halDeviceType == AUDIO_DEVICE_OUT_IP || *halDeviceType == AUDIO_DEVICE_IN_IP) {
1126         if (device.address.getDiscriminator() == DeviceAddress::Address::hidl_discriminator::ipv4) {
1127             const auto& ipv4 = device.address.ipv4();
1128             snprintf(halDeviceAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN, "%d.%d.%d.%d", ipv4[0],
1129                      ipv4[1], ipv4[2], ipv4[3]);
1130         } else {
1131             ALOGE("IP device \"%s\" does not have IPv4 address set", device.deviceType.c_str());
1132             result = BAD_VALUE;
1133         }
1134     } else if (audio_is_usb_out_device(*halDeviceType) || audio_is_usb_in_device(*halDeviceType)) {
1135         if (device.address.getDiscriminator() == DeviceAddress::Address::hidl_discriminator::alsa) {
1136             const auto& alsa = device.address.alsa();
1137             snprintf(halDeviceAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN, "card=%d;device=%d", alsa.card,
1138                      alsa.device);
1139         } else {
1140             ALOGE("USB device \"%s\" does not have ALSA address set", device.deviceType.c_str());
1141             result = BAD_VALUE;
1142         }
1143     } else {
1144         // Any other device type uses the 'id' field.
1145         if (device.address.getDiscriminator() == DeviceAddress::Address::hidl_discriminator::id) {
1146             snprintf(halDeviceAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN, "%s",
1147                      device.address.id().c_str());
1148         }
1149     }
1150     return result;
1151 }
1152 
1153 }  // namespace implementation
1154 }  // namespace CPP_VERSION
1155 }  // namespace common
1156 }  // namespace audio
1157 }  // namespace hardware
1158 }  // namespace android
1159