Audio V4: Cast conversion now deduce both types
That avoids to repeat the destination type which
can change between versions.
Bug: 38184704
Test: compile
Change-Id: I55c881afe5f6fc511ea01b19c5d46de12fb1e0d2
Signed-off-by: Kevin Rocard <krocard@google.com>
diff --git a/audio/common/all-versions/default/Android.bp b/audio/common/all-versions/default/Android.bp
index 8f6b74c..4a27bb7 100644
--- a/audio/common/all-versions/default/Android.bp
+++ b/audio/common/all-versions/default/Android.bp
@@ -33,7 +33,11 @@
],
header_libs: [
+ "android.hardware.audio.common.util@all-versions",
"libaudio_system_headers",
"libhardware_headers",
],
+ export_header_lib_headers: [
+ "android.hardware.audio.common.util@all-versions",
+ ]
}
diff --git a/audio/common/all-versions/default/include/common/all-versions/default/HidlUtils.impl.h b/audio/common/all-versions/default/include/common/all-versions/default/HidlUtils.impl.h
index 26ad518..d6f8d3e 100644
--- a/audio/common/all-versions/default/include/common/all-versions/default/HidlUtils.impl.h
+++ b/audio/common/all-versions/default/include/common/all-versions/default/HidlUtils.impl.h
@@ -18,6 +18,7 @@
#error "AUDIO_HAL_VERSION must be set before including this file."
#endif
+#include <common/all-versions/VersionUtils.h>
#include <string.h>
using ::android::hardware::audio::common::AUDIO_HAL_VERSION::AudioChannelMask;
@@ -32,6 +33,8 @@
using ::android::hardware::audio::common::AUDIO_HAL_VERSION::AudioStreamType;
using ::android::hardware::audio::common::AUDIO_HAL_VERSION::AudioUsage;
+using ::android::hardware::audio::common::utils::mkEnumConverter;
+
namespace android {
namespace hardware {
namespace audio {
@@ -40,7 +43,7 @@
void HidlUtils::audioConfigFromHal(const audio_config_t& halConfig, AudioConfig* config) {
config->sampleRateHz = halConfig.sample_rate;
- config->channelMask = AudioChannelMask(halConfig.channel_mask);
+ config->channelMask = mkEnumConverter<AudioChannelMask>(halConfig.channel_mask);
config->format = AudioFormat(halConfig.format);
audioOffloadInfoFromHal(halConfig.offload_info, &config->offloadInfo);
config->frameCount = halConfig.frame_count;
@@ -58,8 +61,8 @@
void HidlUtils::audioGainConfigFromHal(const struct audio_gain_config& halConfig,
AudioGainConfig* config) {
config->index = halConfig.index;
- config->mode = AudioGainMode(halConfig.mode);
- config->channelMask = AudioChannelMask(halConfig.channel_mask);
+ config->mode = mkEnumConverter<AudioGainMode>(halConfig.mode);
+ config->channelMask = mkEnumConverter<AudioChannelMask>(halConfig.channel_mask);
for (size_t i = 0; i < sizeof(audio_channel_mask_t) * 8; ++i) {
config->values[i] = halConfig.values[i];
}
@@ -79,8 +82,8 @@
}
void HidlUtils::audioGainFromHal(const struct audio_gain& halGain, AudioGain* gain) {
- gain->mode = AudioGainMode(halGain.mode);
- gain->channelMask = AudioChannelMask(halGain.channel_mask);
+ gain->mode = mkEnumConverter<AudioGainMode>(halGain.mode);
+ gain->channelMask = mkEnumConverter<AudioChannelMask>(halGain.channel_mask);
gain->minValue = halGain.min_value;
gain->maxValue = halGain.max_value;
gain->defaultValue = halGain.default_value;
@@ -119,7 +122,7 @@
void HidlUtils::audioOffloadInfoFromHal(const audio_offload_info_t& halOffload,
AudioOffloadInfo* offload) {
offload->sampleRateHz = halOffload.sample_rate;
- offload->channelMask = AudioChannelMask(halOffload.channel_mask);
+ offload->channelMask = mkEnumConverter<AudioChannelMask>(halOffload.channel_mask);
offload->format = AudioFormat(halOffload.format);
offload->streamType = AudioStreamType(halOffload.stream_type);
offload->bitRatePerSecond = halOffload.bit_rate;
@@ -152,9 +155,9 @@
config->id = halConfig.id;
config->role = AudioPortRole(halConfig.role);
config->type = AudioPortType(halConfig.type);
- config->configMask = AudioPortConfigMask(halConfig.config_mask);
+ config->configMask = mkEnumConverter<AudioPortConfigMask>(halConfig.config_mask);
config->sampleRateHz = halConfig.sample_rate;
- config->channelMask = AudioChannelMask(halConfig.channel_mask);
+ config->channelMask = mkEnumConverter<AudioChannelMask>(halConfig.channel_mask);
config->format = AudioFormat(halConfig.format);
audioGainConfigFromHal(halConfig.gain, &config->gain);
switch (halConfig.type) {
@@ -254,7 +257,7 @@
}
port->channelMasks.resize(halPort.num_channel_masks);
for (size_t i = 0; i < halPort.num_channel_masks; ++i) {
- port->channelMasks[i] = AudioChannelMask(halPort.channel_masks[i]);
+ port->channelMasks[i] = mkEnumConverter<AudioChannelMask>(halPort.channel_masks[i]);
}
port->formats.resize(halPort.num_formats);
for (size_t i = 0; i < halPort.num_formats; ++i) {
diff --git a/audio/common/all-versions/util/include/common/all-versions/VersionUtils.h b/audio/common/all-versions/util/include/common/all-versions/VersionUtils.h
new file mode 100644
index 0000000..a998b06
--- /dev/null
+++ b/audio/common/all-versions/util/include/common/all-versions/VersionUtils.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#ifndef android_hardware_audio_common_VersionUtils_H_
+#define android_hardware_audio_common_VersionUtils_H_
+
+#include <hidl/HidlSupport.h>
+#include <type_traits>
+
+namespace android {
+namespace hardware {
+namespace audio {
+namespace common {
+namespace utils {
+
+/** Similar to static_cast but also casts to hidl_bitfield depending on
+ * return type inference (emulated through user-define conversion).
+ */
+template <class Source, class Destination = Source>
+class EnumConverter {
+ public:
+ static_assert(std::is_enum<Source>::value || std::is_enum<Destination>::value,
+ "Source or destination should be an enum");
+
+ explicit EnumConverter(Source source) : mSource(source) {}
+
+ operator Destination() const { return static_cast<Destination>(mSource); }
+
+ template <class = std::enable_if_t<std::is_enum<Destination>::value>>
+ operator ::android::hardware::hidl_bitfield<Destination>() {
+ return static_cast<std::underlying_type_t<Destination>>(mSource);
+ }
+
+ private:
+ const Source mSource;
+};
+template <class Destination, class Source>
+auto mkEnumConverter(Source source) {
+ return EnumConverter<Source, Destination>{source};
+}
+
+} // namespace utils
+} // namespace common
+} // namespace audio
+} // namespace hardware
+} // namespace android
+
+#endif // android_hardware_audio_common_VersionUtils_H_