1 /*
2  * Copyright (C) 2018 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 #ifndef android_hardware_audio_Hidl_Utils_H_
18 #define android_hardware_audio_Hidl_Utils_H_
19 
20 #include PATH(android/hardware/audio/common/FILE_VERSION/types.h)
21 
22 #include <memory>
23 #include <string>
24 #include <vector>
25 
26 #include <system/audio.h>
27 
28 namespace android {
29 namespace hardware {
30 namespace audio {
31 namespace common {
32 namespace CPP_VERSION {
33 namespace implementation {
34 
35 using ::android::hardware::hidl_vec;
36 using namespace ::android::hardware::audio::common::CPP_VERSION;
37 
38 struct HidlUtils {
39     static status_t audioConfigFromHal(const audio_config_t& halConfig, bool isInput,
40                                        AudioConfig* config);
41     static status_t audioConfigToHal(const AudioConfig& config, audio_config_t* halConfig);
42 #if MAJOR_VERSION >= 4
43     static status_t audioContentTypeFromHal(const audio_content_type_t halContentType,
44                                             AudioContentType* contentType);
45     static status_t audioContentTypeToHal(const AudioContentType& contentType,
46                                           audio_content_type_t* halContentType);
47 #endif
48     static status_t audioGainConfigFromHal(const struct audio_gain_config& halConfig, bool isInput,
49                                            AudioGainConfig* config);
50     static status_t audioGainConfigToHal(const AudioGainConfig& config,
51                                          struct audio_gain_config* halConfig);
52     static status_t audioGainFromHal(const struct audio_gain& halGain, bool isInput,
53                                      AudioGain* gain);
54     static status_t audioGainToHal(const AudioGain& gain, struct audio_gain* halGain);
55     static status_t audioUsageFromHal(audio_usage_t halUsage, AudioUsage* usage);
56     static status_t audioUsageToHal(const AudioUsage& usage, audio_usage_t* halUsage);
57     static status_t audioOffloadInfoFromHal(const audio_offload_info_t& halOffload,
58                                             AudioOffloadInfo* offload);
59     static status_t audioOffloadInfoToHal(const AudioOffloadInfo& offload,
60                                           audio_offload_info_t* halOffload);
61     static status_t audioPortConfigFromHal(const struct audio_port_config& halConfig,
62                                            AudioPortConfig* config);
63     static status_t audioPortConfigToHal(const AudioPortConfig& config,
64                                          struct audio_port_config* halConfig);
65     static status_t audioPortConfigsFromHal(unsigned int numHalConfigs,
66                                             const struct audio_port_config* halConfigs,
67                                             hidl_vec<AudioPortConfig>* configs);
68     static status_t audioPortConfigsToHal(const hidl_vec<AudioPortConfig>& configs,
69                                           std::unique_ptr<audio_port_config[]>* halConfigs);
70     static status_t audioPortFromHal(const struct audio_port& halPort, AudioPort* port);
71     static status_t audioPortToHal(const AudioPort& port, struct audio_port* halPort);
72     static status_t audioSourceFromHal(audio_source_t halSource, AudioSource* source);
73     static status_t audioSourceToHal(const AudioSource& source, audio_source_t* halSource);
74 #if MAJOR_VERSION >= 5
75     static status_t deviceAddressToHal(const DeviceAddress& device, audio_devices_t* halDeviceType,
76                                        char* halDeviceAddress);
77     static status_t deviceAddressFromHal(audio_devices_t halDeviceType,
78                                          const char* halDeviceAddress, DeviceAddress* device);
79 #endif
80 
81 #if MAJOR_VERSION >= 7
82     static constexpr char sAudioTagSeparator = ';';
83 
84     static status_t audioChannelMaskFromHal(audio_channel_mask_t halChannelMask, bool isInput,
85                                             AudioChannelMask* channelMask);
86     static status_t audioChannelMasksFromHal(const std::vector<std::string>& halChannelMasks,
87                                              hidl_vec<AudioChannelMask>* channelMasks);
88     static status_t audioChannelMaskToHal(const AudioChannelMask& channelMask,
89                                           audio_channel_mask_t* halChannelMask);
90     static status_t audioConfigBaseFromHal(const audio_config_base_t& halConfigBase, bool isInput,
91                                            AudioConfigBase* configBase);
92     static status_t audioConfigBaseToHal(const AudioConfigBase& configBase,
93                                          audio_config_base_t* halConfigBase);
94     static status_t audioConfigBaseOptionalFromHal(const audio_config_base_t& halConfigBase,
95                                                    bool isInput, bool formatSpecified,
96                                                    bool sampleRateSpecified,
97                                                    bool channelMaskSpecified,
98                                                    AudioConfigBaseOptional* configBase);
99     static status_t audioConfigBaseOptionalToHal(const AudioConfigBaseOptional& configBase,
100                                                  audio_config_base_t* halConfigBase,
101                                                  bool* formatSpecified, bool* sampleRateSpecified,
102                                                  bool* channelMaskSpecified);
103     static status_t audioDeviceTypeFromHal(audio_devices_t halDevice, AudioDevice* device);
104     static status_t audioDeviceTypeToHal(const AudioDevice& device, audio_devices_t* halDevice);
105     static status_t audioFormatFromHal(audio_format_t halFormat, AudioFormat* format);
106     static status_t audioFormatsFromHal(const std::vector<std::string>& halFormats,
107                                         hidl_vec<AudioFormat>* formats);
108     static status_t audioFormatToHal(const AudioFormat& format, audio_format_t* halFormat);
109     static status_t audioGainModeMaskFromHal(audio_gain_mode_t halGainModeMask,
110                                              hidl_vec<AudioGainMode>* gainModeMask);
111     static status_t audioGainModeMaskToHal(const hidl_vec<AudioGainMode>& gainModeMask,
112                                            audio_gain_mode_t* halGainModeMask);
113     static status_t audioPortFromHal(const struct audio_port_v7& halPort, AudioPort* port);
114     static status_t audioPortToHal(const AudioPort& port, struct audio_port_v7* halPort);
115     static status_t audioProfileFromHal(const struct audio_profile& halProfile, bool isInput,
116                                         AudioProfile* profile);
117     static status_t audioProfileToHal(const AudioProfile& profile,
118                                       struct audio_profile* halProfile);
119     static status_t audioStreamTypeFromHal(audio_stream_type_t halStreamType,
120                                            AudioStreamType* streamType);
121     static status_t audioStreamTypeToHal(const AudioStreamType& streamType,
122                                          audio_stream_type_t* halStreamType);
123     static status_t audioTagsFromHal(const std::vector<std::string>& strTags,
124                                      hidl_vec<AudioTag>* tags);
125     static status_t audioTagsToHal(const hidl_vec<AudioTag>& tags, char* halTags);
126     static hidl_vec<AudioTag> filterOutNonVendorTags(const hidl_vec<AudioTag>& tags);
127     static std::vector<std::string> filterOutNonVendorTags(const std::vector<std::string>& tags);
128     static std::vector<std::string> splitAudioTags(const char* halTags);
129     static status_t audioTransportsFromHal(const struct audio_port_v7& halPort, bool isInput,
130                                            hidl_vec<AudioTransport>* transports);
131     static status_t audioTransportsToHal(const hidl_vec<AudioTransport>& transports,
132                                          struct audio_port_v7* halTransport);
133 
134   private:
135     static status_t audioIndexChannelMaskFromHal(audio_channel_mask_t halChannelMask,
136                                                  AudioChannelMask* channelMask);
137     static status_t audioInputChannelMaskFromHal(audio_channel_mask_t halChannelMask,
138                                                  AudioChannelMask* channelMask);
139     static status_t audioOutputChannelMaskFromHal(audio_channel_mask_t halChannelMask,
140                                                   AudioChannelMask* channelMask);
141     static status_t audioPortExtendedInfoFromHal(
142             audio_port_role_t role, audio_port_type_t type,
143             const struct audio_port_config_device_ext& device,
144             const struct audio_port_config_mix_ext& mix,
145             const struct audio_port_config_session_ext& session, AudioPortExtendedInfo* ext,
146             bool* isInput);
147     static status_t audioPortExtendedInfoToHal(const AudioPortExtendedInfo& ext,
148                                                audio_port_role_t* role, audio_port_type_t* type,
149                                                struct audio_port_config_device_ext* device,
150                                                struct audio_port_config_mix_ext* mix,
151                                                struct audio_port_config_session_ext* session);
152     static status_t encapsulationTypeFromHal(audio_encapsulation_type_t halEncapsulationType,
153                                              AudioEncapsulationType* encapsulationType);
154     static status_t encapsulationTypeToHal(const AudioEncapsulationType& encapsulationType,
155                                            audio_encapsulation_type_t* halEncapsulationType);
156 
157 #endif  // MAJOR_VERSION >= 7
158 
159     // V4 and below have DeviceAddress defined in the 'core' interface.
160     // To avoid duplicating code, the implementations of deviceAddressTo/FromHal
161     // are defined as templates. These templates can be only used directly by V4
162     // and below.
163 #if MAJOR_VERSION >= 5
164   private:
165 #endif
166     template <typename DA>
167     static status_t deviceAddressToHalImpl(const DA& device, audio_devices_t* halDeviceType,
168                                            char* halDeviceAddress);
169     template <typename DA>
170     static status_t deviceAddressFromHalImpl(audio_devices_t halDeviceType,
171                                              const char* halDeviceAddress, DA* device);
172 };
173 
174 #if MAJOR_VERSION <= 6
175 #if MAJOR_VERSION >= 4
audioContentTypeFromHal(const audio_content_type_t halContentType,AudioContentType * contentType)176 inline status_t HidlUtils::audioContentTypeFromHal(const audio_content_type_t halContentType,
177                                                    AudioContentType* contentType) {
178     *contentType = AudioContentType(halContentType);
179     return NO_ERROR;
180 }
181 
audioContentTypeToHal(const AudioContentType & contentType,audio_content_type_t * halContentType)182 inline status_t HidlUtils::audioContentTypeToHal(const AudioContentType& contentType,
183                                                  audio_content_type_t* halContentType) {
184     *halContentType = static_cast<audio_content_type_t>(contentType);
185     return NO_ERROR;
186 }
187 #endif
188 
audioSourceFromHal(audio_source_t halSource,AudioSource * source)189 inline status_t HidlUtils::audioSourceFromHal(audio_source_t halSource, AudioSource* source) {
190     *source = AudioSource(halSource);
191     return NO_ERROR;
192 }
193 
audioSourceToHal(const AudioSource & source,audio_source_t * halSource)194 inline status_t HidlUtils::audioSourceToHal(const AudioSource& source, audio_source_t* halSource) {
195     *halSource = static_cast<audio_source_t>(source);
196     return NO_ERROR;
197 }
198 
199 template <typename DA>
deviceAddressToHalImpl(const DA & device,audio_devices_t * halDeviceType,char * halDeviceAddress)200 status_t HidlUtils::deviceAddressToHalImpl(const DA& device, audio_devices_t* halDeviceType,
201                                            char* halDeviceAddress) {
202     *halDeviceType = static_cast<audio_devices_t>(device.device);
203     memset(halDeviceAddress, 0, AUDIO_DEVICE_MAX_ADDRESS_LEN);
204     if (audio_is_a2dp_out_device(*halDeviceType) || audio_is_a2dp_in_device(*halDeviceType)) {
205         snprintf(halDeviceAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN, "%02X:%02X:%02X:%02X:%02X:%02X",
206                  device.address.mac[0], device.address.mac[1], device.address.mac[2],
207                  device.address.mac[3], device.address.mac[4], device.address.mac[5]);
208     } else if (*halDeviceType == AUDIO_DEVICE_OUT_IP || *halDeviceType == AUDIO_DEVICE_IN_IP) {
209         snprintf(halDeviceAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN, "%d.%d.%d.%d",
210                  device.address.ipv4[0], device.address.ipv4[1], device.address.ipv4[2],
211                  device.address.ipv4[3]);
212     } else if (audio_is_usb_out_device(*halDeviceType) || audio_is_usb_in_device(*halDeviceType)) {
213         snprintf(halDeviceAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN, "card=%d;device=%d",
214                  device.address.alsa.card, device.address.alsa.device);
215     } else if (*halDeviceType == AUDIO_DEVICE_OUT_BUS || *halDeviceType == AUDIO_DEVICE_IN_BUS) {
216         snprintf(halDeviceAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN, "%s", device.busAddress.c_str());
217     } else if (*halDeviceType == AUDIO_DEVICE_OUT_REMOTE_SUBMIX ||
218                *halDeviceType == AUDIO_DEVICE_IN_REMOTE_SUBMIX) {
219         snprintf(halDeviceAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN, "%s",
220                  device.rSubmixAddress.c_str());
221     } else {
222         // Fall back to bus address for other device types, e.g. for microphones.
223         snprintf(halDeviceAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN, "%s", device.busAddress.c_str());
224     }
225     return NO_ERROR;
226 }
227 
228 template <typename DA>
deviceAddressFromHalImpl(audio_devices_t halDeviceType,const char * halDeviceAddress,DA * device)229 status_t HidlUtils::deviceAddressFromHalImpl(audio_devices_t halDeviceType,
230                                              const char* halDeviceAddress, DA* device) {
231     if (device == nullptr) {
232         return BAD_VALUE;
233     }
234     device->device = AudioDevice(halDeviceType);
235     if (halDeviceAddress == nullptr ||
236         strnlen(halDeviceAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN) == 0) {
237         return NO_ERROR;
238     }
239 
240     if (audio_is_a2dp_out_device(halDeviceType) || audio_is_a2dp_in_device(halDeviceType)) {
241         int status =
242                 sscanf(halDeviceAddress, "%hhX:%hhX:%hhX:%hhX:%hhX:%hhX", &device->address.mac[0],
243                        &device->address.mac[1], &device->address.mac[2], &device->address.mac[3],
244                        &device->address.mac[4], &device->address.mac[5]);
245         return status == 6 ? OK : BAD_VALUE;
246     } else if (halDeviceType == AUDIO_DEVICE_OUT_IP || halDeviceType == AUDIO_DEVICE_IN_IP) {
247         int status = sscanf(halDeviceAddress, "%hhu.%hhu.%hhu.%hhu", &device->address.ipv4[0],
248                             &device->address.ipv4[1], &device->address.ipv4[2],
249                             &device->address.ipv4[3]);
250         return status == 4 ? OK : BAD_VALUE;
251     } else if (audio_is_usb_out_device(halDeviceType) || audio_is_usb_in_device(halDeviceType)) {
252         int status = sscanf(halDeviceAddress, "card=%d;device=%d", &device->address.alsa.card,
253                             &device->address.alsa.device);
254         return status == 2 ? OK : BAD_VALUE;
255     } else if (halDeviceType == AUDIO_DEVICE_OUT_BUS || halDeviceType == AUDIO_DEVICE_IN_BUS) {
256         device->busAddress = halDeviceAddress;
257         return OK;
258     } else if (halDeviceType == AUDIO_DEVICE_OUT_REMOTE_SUBMIX ||
259                halDeviceType == AUDIO_DEVICE_IN_REMOTE_SUBMIX) {
260         device->rSubmixAddress = halDeviceAddress;
261         return OK;
262     }
263     // Fall back to bus address for other device types, e.g. for microphones.
264     device->busAddress = halDeviceAddress;
265     return NO_ERROR;
266 }
267 #endif  // MAJOR_VERSION <= 6
268 
269 }  // namespace implementation
270 }  // namespace CPP_VERSION
271 }  // namespace common
272 }  // namespace audio
273 }  // namespace hardware
274 }  // namespace android
275 
276 #endif  // android_hardware_audio_Hidl_Utils_H_
277