From b52e93f5165c5f909e2a22478891750870969a88 Mon Sep 17 00:00:00 2001 From: Mikhail Naganov Date: Thu, 10 Dec 2020 16:10:08 -0800 Subject: [PATCH] audio: Extend HidlUtils for the default wrapper needs Add conversions used by the default wrapper. Promote some conversions to pre-V7 interface to reduce version-based forking in the default wrapper code. Bug: 142480271 Test: atest android.hardware.audio.common@7.0-util_tests Change-Id: I93c482eeaf08442271be2656693be5395ca53762 Merged-In: I93c482eeaf08442271be2656693be5395ca53762 --- ...id_audio_policy_configuration_V7_0-enums.h | 8 + .../all-versions/default/7.0/HidlUtils.cpp | 59 ++++++ audio/common/all-versions/default/Android.bp | 2 + .../common/all-versions/default/HidlUtils.cpp | 26 ++- audio/common/all-versions/default/HidlUtils.h | 183 +++++++++++++----- .../all-versions/default/HidlUtilsCommon.cpp | 58 ++++++ .../default/tests/hidlutils_tests.cpp | 78 ++++++++ 7 files changed, 363 insertions(+), 51 deletions(-) create mode 100644 audio/common/all-versions/default/HidlUtilsCommon.cpp diff --git a/audio/common/7.0/enums/include/android_audio_policy_configuration_V7_0-enums.h b/audio/common/7.0/enums/include/android_audio_policy_configuration_V7_0-enums.h index 414eede6d1..b7c1cc97bc 100644 --- a/audio/common/7.0/enums/include/android_audio_policy_configuration_V7_0-enums.h +++ b/audio/common/7.0/enums/include/android_audio_policy_configuration_V7_0-enums.h @@ -225,6 +225,10 @@ static inline bool isUnknownAudioChannelMask(const std::string& mask) { return stringToAudioChannelMask(mask) == AudioChannelMask::UNKNOWN; } +static inline bool isUnknownAudioContentType(const std::string& contentType) { + return stringToAudioContentType(contentType) == AudioContentType::UNKNOWN; +} + static inline bool isUnknownAudioDevice(const std::string& device) { return stringToAudioDevice(device) == AudioDevice::UNKNOWN && !isVendorExtension(device); } @@ -237,6 +241,10 @@ static inline bool isUnknownAudioGainMode(const std::string& mode) { return stringToAudioGainMode(mode) == AudioGainMode::UNKNOWN; } +static inline bool isUnknownAudioInOutFlag(const std::string& flag) { + return stringToAudioInOutFlag(flag) == AudioInOutFlag::UNKNOWN; +} + static inline bool isUnknownAudioSource(const std::string& source) { return stringToAudioSource(source) == AudioSource::UNKNOWN; } diff --git a/audio/common/all-versions/default/7.0/HidlUtils.cpp b/audio/common/all-versions/default/7.0/HidlUtils.cpp index 1a662825bd..c985a7027a 100644 --- a/audio/common/all-versions/default/7.0/HidlUtils.cpp +++ b/audio/common/all-versions/default/7.0/HidlUtils.cpp @@ -95,6 +95,25 @@ status_t HidlUtils::audioChannelMaskFromHal(audio_channel_mask_t halChannelMask, return NO_ERROR; } +status_t HidlUtils::audioChannelMasksFromHal(const std::vector& halChannelMasks, + hidl_vec* channelMasks) { + hidl_vec tempChannelMasks; + tempChannelMasks.resize(halChannelMasks.size()); + size_t tempPos = 0; + for (const auto& halChannelMask : halChannelMasks) { + if (!halChannelMask.empty() && !xsd::isUnknownAudioChannelMask(halChannelMask)) { + tempChannelMasks[tempPos++] = halChannelMask; + } + } + if (tempPos == tempChannelMasks.size()) { + *channelMasks = std::move(tempChannelMasks); + } else { + *channelMasks = hidl_vec(tempChannelMasks.begin(), + tempChannelMasks.begin() + tempPos); + } + return halChannelMasks.size() == channelMasks->size() ? NO_ERROR : BAD_VALUE; +} + status_t HidlUtils::audioChannelMaskToHal(const AudioChannelMask& channelMask, audio_channel_mask_t* halChannelMask) { if (!xsd::isUnknownAudioChannelMask(channelMask) && @@ -127,6 +146,28 @@ status_t HidlUtils::audioConfigBaseToHal(const AudioConfigBase& configBase, return result; } +status_t HidlUtils::audioContentTypeFromHal(const audio_content_type_t halContentType, + AudioContentType* contentType) { + *contentType = audio_content_type_to_string(halContentType); + if (!contentType->empty() && !xsd::isUnknownAudioContentType(*contentType)) { + return NO_ERROR; + } + ALOGE("Unknown audio content type value 0x%X", halContentType); + *contentType = toString(xsd::AudioContentType::AUDIO_CONTENT_TYPE_UNKNOWN); + return BAD_VALUE; +} + +status_t HidlUtils::audioContentTypeToHal(const AudioContentType& contentType, + audio_content_type_t* halContentType) { + if (!xsd::isUnknownAudioContentType(contentType) && + audio_content_type_from_string(contentType.c_str(), halContentType)) { + return NO_ERROR; + } + ALOGE("Unknown audio content type \"%s\"", contentType.c_str()); + *halContentType = AUDIO_CONTENT_TYPE_UNKNOWN; + return BAD_VALUE; +} + status_t HidlUtils::audioDeviceTypeFromHal(audio_devices_t halDevice, AudioDevice* device) { *device = audio_device_to_string(halDevice); if (!device->empty() && !xsd::isUnknownAudioDevice(*device)) { @@ -155,6 +196,24 @@ status_t HidlUtils::audioFormatFromHal(audio_format_t halFormat, AudioFormat* fo return BAD_VALUE; } +status_t HidlUtils::audioFormatsFromHal(const std::vector& halFormats, + hidl_vec* formats) { + hidl_vec tempFormats; + tempFormats.resize(halFormats.size()); + size_t tempPos = 0; + for (const auto& halFormat : halFormats) { + if (!halFormat.empty() && !xsd::isUnknownAudioFormat(halFormat)) { + tempFormats[tempPos++] = halFormat; + } + } + if (tempPos == tempFormats.size()) { + *formats = std::move(tempFormats); + } else { + *formats = hidl_vec(tempFormats.begin(), tempFormats.begin() + tempPos); + } + return halFormats.size() == formats->size() ? NO_ERROR : BAD_VALUE; +} + status_t HidlUtils::audioFormatToHal(const AudioFormat& format, audio_format_t* halFormat) { if (!xsd::isUnknownAudioFormat(format) && audio_format_from_string(format.c_str(), halFormat)) { return NO_ERROR; diff --git a/audio/common/all-versions/default/Android.bp b/audio/common/all-versions/default/Android.bp index b83a58a3ec..45f0b8f297 100644 --- a/audio/common/all-versions/default/Android.bp +++ b/audio/common/all-versions/default/Android.bp @@ -43,6 +43,7 @@ filegroup { name: "android.hardware.audio.common-util@2-6", srcs: [ "HidlUtils.cpp", + "HidlUtilsCommon.cpp", "UuidUtils.cpp", ], } @@ -132,6 +133,7 @@ cc_library { defaults: ["android.hardware.audio.common-util_default"], srcs: [ "7.0/HidlUtils.cpp", + "HidlUtilsCommon.cpp", "UuidUtils.cpp", ], shared_libs: [ diff --git a/audio/common/all-versions/default/HidlUtils.cpp b/audio/common/all-versions/default/HidlUtils.cpp index ab3c1c7b33..c0dcd80ac0 100644 --- a/audio/common/all-versions/default/HidlUtils.cpp +++ b/audio/common/all-versions/default/HidlUtils.cpp @@ -28,7 +28,7 @@ namespace common { namespace CPP_VERSION { namespace implementation { -status_t HidlUtils::audioConfigFromHal(const audio_config_t& halConfig, AudioConfig* config) { +status_t HidlUtils::audioConfigFromHal(const audio_config_t& halConfig, bool, AudioConfig* config) { config->sampleRateHz = halConfig.sample_rate; config->channelMask = EnumBitfield(halConfig.channel_mask); config->format = AudioFormat(halConfig.format); @@ -47,8 +47,8 @@ status_t HidlUtils::audioConfigToHal(const AudioConfig& config, audio_config_t* return NO_ERROR; } -void HidlUtils::audioGainConfigFromHal(const struct audio_gain_config& halConfig, - AudioGainConfig* config) { +status_t HidlUtils::audioGainConfigFromHal(const struct audio_gain_config& halConfig, bool, + AudioGainConfig* config) { config->index = halConfig.index; config->mode = EnumBitfield(halConfig.mode); config->channelMask = EnumBitfield(halConfig.channel_mask); @@ -56,6 +56,7 @@ void HidlUtils::audioGainConfigFromHal(const struct audio_gain_config& halConfig config->values[i] = halConfig.values[i]; } config->rampDurationMs = halConfig.ramp_duration_ms; + return NO_ERROR; } status_t HidlUtils::audioGainConfigToHal(const AudioGainConfig& config, @@ -71,7 +72,7 @@ status_t HidlUtils::audioGainConfigToHal(const AudioGainConfig& config, return NO_ERROR; } -void HidlUtils::audioGainFromHal(const struct audio_gain& halGain, AudioGain* gain) { +status_t HidlUtils::audioGainFromHal(const struct audio_gain& halGain, bool, AudioGain* gain) { gain->mode = EnumBitfield(halGain.mode); gain->channelMask = EnumBitfield(halGain.channel_mask); gain->minValue = halGain.min_value; @@ -80,6 +81,7 @@ void HidlUtils::audioGainFromHal(const struct audio_gain& halGain, AudioGain* ga gain->stepValue = halGain.step_value; gain->minRampMs = halGain.min_ramp_ms; gain->maxRampMs = halGain.max_ramp_ms; + return NO_ERROR; } status_t HidlUtils::audioGainToHal(const AudioGain& gain, struct audio_gain* halGain) { @@ -182,7 +184,7 @@ status_t HidlUtils::audioPortConfigFromHal(const struct audio_port_config& halCo config->sampleRateHz = halConfig.sample_rate; config->channelMask = EnumBitfield(halConfig.channel_mask); config->format = AudioFormat(halConfig.format); - audioGainConfigFromHal(halConfig.gain, &config->gain); + audioGainConfigFromHal(halConfig.gain, false /*isInput--ignored*/, &config->gain); switch (halConfig.type) { case AUDIO_PORT_TYPE_NONE: break; @@ -272,7 +274,7 @@ status_t HidlUtils::audioPortFromHal(const struct audio_port& halPort, AudioPort } port->gains.resize(halPort.num_gains); for (size_t i = 0; i < halPort.num_gains; ++i) { - audioGainFromHal(halPort.gains[i], &port->gains[i]); + audioGainFromHal(halPort.gains[i], false /*isInput--ignored*/, &port->gains[i]); } audioPortConfigFromHal(halPort.active_config, &port->activeConfig); switch (halPort.type) { @@ -351,6 +353,18 @@ status_t HidlUtils::audioPortToHal(const AudioPort& port, struct audio_port* hal return NO_ERROR; } +#if MAJOR_VERSION >= 5 +status_t HidlUtils::deviceAddressToHal(const DeviceAddress& device, audio_devices_t* halDeviceType, + char* halDeviceAddress) { + return deviceAddressToHalImpl(device, halDeviceType, halDeviceAddress); +} + +status_t HidlUtils::deviceAddressFromHal(audio_devices_t halDeviceType, + const char* halDeviceAddress, DeviceAddress* device) { + return deviceAddressFromHalImpl(halDeviceType, halDeviceAddress, device); +} +#endif + } // namespace implementation } // namespace CPP_VERSION } // namespace common diff --git a/audio/common/all-versions/default/HidlUtils.h b/audio/common/all-versions/default/HidlUtils.h index 4e609ca4fd..c420a2f712 100644 --- a/audio/common/all-versions/default/HidlUtils.h +++ b/audio/common/all-versions/default/HidlUtils.h @@ -23,8 +23,6 @@ #include -using ::android::hardware::hidl_vec; - namespace android { namespace hardware { namespace audio { @@ -32,25 +30,25 @@ namespace common { namespace CPP_VERSION { namespace implementation { +using ::android::hardware::hidl_vec; using namespace ::android::hardware::audio::common::CPP_VERSION; struct HidlUtils { -#if MAJOR_VERSION < 7 - static status_t audioConfigFromHal(const audio_config_t& halConfig, AudioConfig* config); - static void audioGainConfigFromHal(const struct audio_gain_config& halConfig, - AudioGainConfig* config); - static void audioGainFromHal(const struct audio_gain& halGain, AudioGain* gain); -#else static status_t audioConfigFromHal(const audio_config_t& halConfig, bool isInput, AudioConfig* config); + static status_t audioConfigToHal(const AudioConfig& config, audio_config_t* halConfig); +#if MAJOR_VERSION >= 4 + static status_t audioContentTypeFromHal(const audio_content_type_t halContentType, + AudioContentType* contentType); + static status_t audioContentTypeToHal(const AudioContentType& contentType, + audio_content_type_t* halContentType); +#endif static status_t audioGainConfigFromHal(const struct audio_gain_config& halConfig, bool isInput, AudioGainConfig* config); - static status_t audioGainFromHal(const struct audio_gain& halGain, bool isInput, - AudioGain* gain); -#endif - static status_t audioConfigToHal(const AudioConfig& config, audio_config_t* halConfig); static status_t audioGainConfigToHal(const AudioGainConfig& config, struct audio_gain_config* halConfig); + static status_t audioGainFromHal(const struct audio_gain& halGain, bool isInput, + AudioGain* gain); static status_t audioGainToHal(const AudioGain& gain, struct audio_gain* halGain); static status_t audioUsageFromHal(audio_usage_t halUsage, AudioUsage* usage); static status_t audioUsageToHal(const AudioUsage& usage, audio_usage_t* halUsage); @@ -64,43 +62,37 @@ struct HidlUtils { struct audio_port_config* halConfig); static status_t audioPortConfigsFromHal(unsigned int numHalConfigs, const struct audio_port_config* halConfigs, - hidl_vec* configs) { - status_t result = NO_ERROR; - configs->resize(numHalConfigs); - for (unsigned int i = 0; i < numHalConfigs; ++i) { - if (status_t status = audioPortConfigFromHal(halConfigs[i], &(*configs)[i]); - status != NO_ERROR) { - result = status; - } - } - return result; - } + hidl_vec* configs); static status_t audioPortConfigsToHal(const hidl_vec& configs, - std::unique_ptr* halConfigs) { - status_t result = NO_ERROR; - halConfigs->reset(new audio_port_config[configs.size()]); - for (size_t i = 0; i < configs.size(); ++i) { - if (status_t status = audioPortConfigToHal(configs[i], &(*halConfigs)[i]); - status != NO_ERROR) { - result = status; - } - } - return result; - } + std::unique_ptr* halConfigs); + static status_t audioPortFromHal(const struct audio_port& halPort, AudioPort* port); + static status_t audioPortToHal(const AudioPort& port, struct audio_port* halPort); + static status_t audioSourceFromHal(audio_source_t halSource, AudioSource* source); + static status_t audioSourceToHal(const AudioSource& source, audio_source_t* halSource); +#if MAJOR_VERSION >= 5 + static status_t deviceAddressToHal(const DeviceAddress& device, audio_devices_t* halDeviceType, + char* halDeviceAddress); + static status_t deviceAddressFromHal(audio_devices_t halDeviceType, + const char* halDeviceAddress, DeviceAddress* device); +#endif - // PLEASE DO NOT USE, will be removed in a couple of days +#if MAJOR_VERSION <= 6 + // Temporary versions for compatibility with forks of the default implementation. + // Will be removed, do not use! + static status_t audioConfigFromHal(const audio_config_t& halConfig, AudioConfig* config) { + return audioConfigFromHal(halConfig, false /*isInput--ignored*/, config); + } static std::unique_ptr audioPortConfigsToHal( const hidl_vec& configs) { std::unique_ptr halConfigs; (void)audioPortConfigsToHal(configs, &halConfigs); return halConfigs; } - - static status_t audioPortFromHal(const struct audio_port& halPort, AudioPort* port); - static status_t audioPortToHal(const AudioPort& port, struct audio_port* halPort); -#if MAJOR_VERSION >= 7 +#else // V7 and above static status_t audioChannelMaskFromHal(audio_channel_mask_t halChannelMask, bool isInput, AudioChannelMask* channelMask); + static status_t audioChannelMasksFromHal(const std::vector& halChannelMasks, + hidl_vec* channelMasks); static status_t audioChannelMaskToHal(const AudioChannelMask& channelMask, audio_channel_mask_t* halChannelMask); static status_t audioConfigBaseFromHal(const audio_config_base_t& halConfigBase, bool isInput, @@ -110,6 +102,8 @@ struct HidlUtils { static status_t audioDeviceTypeFromHal(audio_devices_t halDevice, AudioDevice* device); static status_t audioDeviceTypeToHal(const AudioDevice& device, audio_devices_t* halDevice); static status_t audioFormatFromHal(audio_format_t halFormat, AudioFormat* format); + static status_t audioFormatsFromHal(const std::vector& halFormats, + hidl_vec* formats); static status_t audioFormatToHal(const AudioFormat& format, audio_format_t* halFormat); static status_t audioGainModeMaskFromHal(audio_gain_mode_t halGainModeMask, hidl_vec* gainModeMask); @@ -121,16 +115,10 @@ struct HidlUtils { AudioProfile* profile); static status_t audioProfileToHal(const AudioProfile& profile, struct audio_profile* halProfile); - static status_t audioSourceFromHal(audio_source_t halSource, AudioSource* source); - static status_t audioSourceToHal(const AudioSource& source, audio_source_t* halSource); static status_t audioStreamTypeFromHal(audio_stream_type_t halStreamType, AudioStreamType* streamType); static status_t audioStreamTypeToHal(const AudioStreamType& streamType, audio_stream_type_t* halStreamType); - static status_t deviceAddressToHal(const DeviceAddress& device, audio_devices_t* halDeviceType, - char* halDeviceAddress); - static status_t deviceAddressFromHal(audio_devices_t halDeviceType, - const char* halDeviceAddress, DeviceAddress* device); private: static status_t audioIndexChannelMaskFromHal(audio_channel_mask_t halChannelMask, @@ -151,8 +139,113 @@ struct HidlUtils { struct audio_port_config_mix_ext* mix, struct audio_port_config_session_ext* session); #endif + + // V4 and below have DeviceAddress defined in the 'core' interface. + // To avoid duplicating code, the implementations of deviceAddressTo/FromHal + // are defined as templates. These templates can be only used directly by V4 + // and below. +#if MAJOR_VERSION >= 5 + private: +#endif + template + static status_t deviceAddressToHalImpl(const DA& device, audio_devices_t* halDeviceType, + char* halDeviceAddress); + template + static status_t deviceAddressFromHalImpl(audio_devices_t halDeviceType, + const char* halDeviceAddress, DA* device); }; +#if MAJOR_VERSION <= 6 +#if MAJOR_VERSION >= 4 +inline status_t HidlUtils::audioContentTypeFromHal(const audio_content_type_t halContentType, + AudioContentType* contentType) { + *contentType = AudioContentType(halContentType); + return NO_ERROR; +} + +inline status_t HidlUtils::audioContentTypeToHal(const AudioContentType& contentType, + audio_content_type_t* halContentType) { + *halContentType = static_cast(contentType); + return NO_ERROR; +} +#endif + +inline status_t HidlUtils::audioSourceFromHal(audio_source_t halSource, AudioSource* source) { + *source = AudioSource(halSource); + return NO_ERROR; +} + +inline status_t HidlUtils::audioSourceToHal(const AudioSource& source, audio_source_t* halSource) { + *halSource = static_cast(source); + return NO_ERROR; +} + +template +status_t HidlUtils::deviceAddressToHalImpl(const DA& device, audio_devices_t* halDeviceType, + char* halDeviceAddress) { + *halDeviceType = static_cast(device.device); + memset(halDeviceAddress, 0, AUDIO_DEVICE_MAX_ADDRESS_LEN); + if (audio_is_a2dp_out_device(*halDeviceType) || audio_is_a2dp_in_device(*halDeviceType)) { + snprintf(halDeviceAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN, "%02X:%02X:%02X:%02X:%02X:%02X", + device.address.mac[0], device.address.mac[1], device.address.mac[2], + device.address.mac[3], device.address.mac[4], device.address.mac[5]); + } else if (*halDeviceType == AUDIO_DEVICE_OUT_IP || *halDeviceType == AUDIO_DEVICE_IN_IP) { + snprintf(halDeviceAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN, "%d.%d.%d.%d", + device.address.ipv4[0], device.address.ipv4[1], device.address.ipv4[2], + device.address.ipv4[3]); + } else if (audio_is_usb_out_device(*halDeviceType) || audio_is_usb_in_device(*halDeviceType)) { + snprintf(halDeviceAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN, "card=%d;device=%d", + device.address.alsa.card, device.address.alsa.device); + } else if (*halDeviceType == AUDIO_DEVICE_OUT_BUS || *halDeviceType == AUDIO_DEVICE_IN_BUS) { + snprintf(halDeviceAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN, "%s", device.busAddress.c_str()); + } else if (*halDeviceType == AUDIO_DEVICE_OUT_REMOTE_SUBMIX || + *halDeviceType == AUDIO_DEVICE_IN_REMOTE_SUBMIX) { + snprintf(halDeviceAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN, "%s", + device.rSubmixAddress.c_str()); + } + return NO_ERROR; +} + +template +status_t HidlUtils::deviceAddressFromHalImpl(audio_devices_t halDeviceType, + const char* halDeviceAddress, DA* device) { + if (device == nullptr) { + return BAD_VALUE; + } + device->device = AudioDevice(halDeviceType); + if (halDeviceAddress == nullptr || + strnlen(halDeviceAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN) == 0) { + return NO_ERROR; + } + + if (audio_is_a2dp_out_device(halDeviceType) || audio_is_a2dp_in_device(halDeviceType)) { + int status = + sscanf(halDeviceAddress, "%hhX:%hhX:%hhX:%hhX:%hhX:%hhX", &device->address.mac[0], + &device->address.mac[1], &device->address.mac[2], &device->address.mac[3], + &device->address.mac[4], &device->address.mac[5]); + return status == 6 ? OK : BAD_VALUE; + } else if (halDeviceType == AUDIO_DEVICE_OUT_IP || halDeviceType == AUDIO_DEVICE_IN_IP) { + int status = sscanf(halDeviceAddress, "%hhu.%hhu.%hhu.%hhu", &device->address.ipv4[0], + &device->address.ipv4[1], &device->address.ipv4[2], + &device->address.ipv4[3]); + return status == 4 ? OK : BAD_VALUE; + } else if (audio_is_usb_out_device(halDeviceType) || audio_is_usb_in_device(halDeviceType)) { + int status = sscanf(halDeviceAddress, "card=%d;device=%d", &device->address.alsa.card, + &device->address.alsa.device); + return status == 2 ? OK : BAD_VALUE; + } else if (halDeviceType == AUDIO_DEVICE_OUT_BUS || halDeviceType == AUDIO_DEVICE_IN_BUS) { + device->busAddress = halDeviceAddress; + return OK; + } else if (halDeviceType == AUDIO_DEVICE_OUT_REMOTE_SUBMIX || + halDeviceType == AUDIO_DEVICE_IN_REMOTE_SUBMIX) { + device->rSubmixAddress = halDeviceAddress; + return OK; + } + device->busAddress = halDeviceAddress; + return NO_ERROR; +} +#endif // MAJOR_VERSION <= 6 + } // namespace implementation } // namespace CPP_VERSION } // namespace common diff --git a/audio/common/all-versions/default/HidlUtilsCommon.cpp b/audio/common/all-versions/default/HidlUtilsCommon.cpp new file mode 100644 index 0000000000..d2da1939f5 --- /dev/null +++ b/audio/common/all-versions/default/HidlUtilsCommon.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "HidlUtils.h" + +namespace android { +namespace hardware { +namespace audio { +namespace common { +namespace CPP_VERSION { +namespace implementation { + +status_t HidlUtils::audioPortConfigsFromHal(unsigned int numHalConfigs, + const struct audio_port_config* halConfigs, + hidl_vec* configs) { + status_t result = NO_ERROR; + configs->resize(numHalConfigs); + for (unsigned int i = 0; i < numHalConfigs; ++i) { + if (status_t status = audioPortConfigFromHal(halConfigs[i], &(*configs)[i]); + status != NO_ERROR) { + result = status; + } + } + return result; +} + +status_t HidlUtils::audioPortConfigsToHal(const hidl_vec& configs, + std::unique_ptr* halConfigs) { + status_t result = NO_ERROR; + halConfigs->reset(new audio_port_config[configs.size()]); + for (size_t i = 0; i < configs.size(); ++i) { + if (status_t status = audioPortConfigToHal(configs[i], &(*halConfigs)[i]); + status != NO_ERROR) { + result = status; + } + } + return result; +} + +} // namespace implementation +} // namespace CPP_VERSION +} // namespace common +} // namespace audio +} // namespace hardware +} // namespace android diff --git a/audio/common/all-versions/default/tests/hidlutils_tests.cpp b/audio/common/all-versions/default/tests/hidlutils_tests.cpp index bfc99e6b48..22571c0411 100644 --- a/audio/common/all-versions/default/tests/hidlutils_tests.cpp +++ b/audio/common/all-versions/default/tests/hidlutils_tests.cpp @@ -28,6 +28,7 @@ #include using namespace android; +using ::android::hardware::hidl_vec; using namespace ::android::hardware::audio::common::CPP_VERSION; using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils; namespace xsd { @@ -36,6 +37,8 @@ using namespace ::android::audio::policy::configuration::V7_0; static constexpr audio_channel_mask_t kInvalidHalChannelMask = static_cast(0xFFFFFFFFU); +static constexpr audio_content_type_t kInvalidHalContentType = + static_cast(0xFFFFFFFFU); static constexpr audio_devices_t kInvalidHalDevice = static_cast(0xFFFFFFFFU); static constexpr audio_format_t kInvalidHalFormat = static_cast(0xFFFFFFFFU); static constexpr audio_gain_mode_t kInvalidHalGainMode = @@ -117,6 +120,34 @@ TEST(HidlUtils, ConvertChannelMask) { } } +TEST(HidlUtils, ConvertInvalidChannelMasksFromHal) { + std::vector validAndInvalidChannelMasks = { + toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO), "random string", ""}; + hidl_vec validChannelMask; + EXPECT_EQ(BAD_VALUE, + HidlUtils::audioChannelMasksFromHal(validAndInvalidChannelMasks, &validChannelMask)); + EXPECT_EQ(1, validChannelMask.size()); + EXPECT_EQ(validAndInvalidChannelMasks[0], validChannelMask[0]); + + std::vector invalidChannelMasks = {"random string", ""}; + hidl_vec empty; + EXPECT_EQ(BAD_VALUE, HidlUtils::audioChannelMasksFromHal(invalidChannelMasks, &empty)); + EXPECT_EQ(0, empty.size()); +} + +TEST(HidlUtils, ConvertChannelMasksFromHal) { + std::vector allHalChannelMasks; + for (const auto enumVal : xsdc_enum_range{}) { + allHalChannelMasks.push_back(toString(enumVal)); + } + hidl_vec allChannelMasks; + EXPECT_EQ(NO_ERROR, HidlUtils::audioChannelMasksFromHal(allHalChannelMasks, &allChannelMasks)); + EXPECT_EQ(allHalChannelMasks.size(), allChannelMasks.size()); + for (size_t i = 0; i < allHalChannelMasks.size(); ++i) { + EXPECT_EQ(allHalChannelMasks[i], allChannelMasks[i]); + } +} + TEST(HidlUtils, ConvertInvalidConfigBase) { AudioConfigBase invalid; EXPECT_EQ(BAD_VALUE, HidlUtils::audioConfigBaseFromHal({.sample_rate = 0, @@ -147,6 +178,26 @@ TEST(HidlUtils, ConvertConfigBase) { EXPECT_EQ(configBase, configBaseBack); } +TEST(HidlUtils, ConvertInvalidContentType) { + AudioContentType invalid; + EXPECT_EQ(BAD_VALUE, HidlUtils::audioContentTypeFromHal(kInvalidHalContentType, &invalid)); + audio_content_type_t halInvalid; + EXPECT_EQ(BAD_VALUE, HidlUtils::audioContentTypeToHal("random string", &halInvalid)); +} + +TEST(HidlUtils, ConvertContentType) { + for (const auto enumVal : xsdc_enum_range{}) { + const AudioContentType contentType = toString(enumVal); + audio_content_type_t halContentType; + AudioContentType contentTypeBack; + EXPECT_EQ(NO_ERROR, HidlUtils::audioContentTypeToHal(contentType, &halContentType)) + << "Conversion of \"" << contentType << "\" failed"; + EXPECT_EQ(NO_ERROR, HidlUtils::audioContentTypeFromHal(halContentType, &contentTypeBack)) + << "Conversion of content type " << halContentType << " failed"; + EXPECT_EQ(contentType, contentTypeBack); + } +} + TEST(HidlUtils, ConvertInvalidDeviceType) { AudioDevice invalid; EXPECT_EQ(BAD_VALUE, HidlUtils::audioDeviceTypeFromHal(kInvalidHalDevice, &invalid)); @@ -314,6 +365,33 @@ TEST(HidlUtils, ConvertFormat) { } } +TEST(HidlUtils, ConvertInvalidFormatsFromHal) { + std::vector validAndInvalidFormats = { + toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT), "random string", ""}; + hidl_vec validFormat; + EXPECT_EQ(BAD_VALUE, HidlUtils::audioFormatsFromHal(validAndInvalidFormats, &validFormat)); + EXPECT_EQ(1, validFormat.size()); + EXPECT_EQ(validAndInvalidFormats[0], validFormat[0]); + + std::vector invalidFormats = {"random string", ""}; + hidl_vec empty; + EXPECT_EQ(BAD_VALUE, HidlUtils::audioFormatsFromHal(invalidFormats, &empty)); + EXPECT_EQ(0, empty.size()); +} + +TEST(HidlUtils, ConvertFormatsFromHal) { + std::vector allHalFormats; + for (const auto enumVal : xsdc_enum_range{}) { + allHalFormats.push_back(toString(enumVal)); + } + hidl_vec allFormats; + EXPECT_EQ(NO_ERROR, HidlUtils::audioFormatsFromHal(allHalFormats, &allFormats)); + EXPECT_EQ(allHalFormats.size(), allFormats.size()); + for (size_t i = 0; i < allHalFormats.size(); ++i) { + EXPECT_EQ(allHalFormats[i], allFormats[i]); + } +} + TEST(HidlUtils, ConvertInvalidGainModeMask) { hidl_vec invalid; EXPECT_EQ(BAD_VALUE, HidlUtils::audioGainModeMaskFromHal(kInvalidHalGainMode, &invalid));