1 /*
2  * Copyright (C) 2015 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 "TypeConverter.h"
18 
19 namespace android {
20 
21 #define MAKE_STRING_FROM_ENUM(string) { #string, string }
22 
23 template <>
24 const DeviceConverter::Table DeviceConverter::mTable[] = {
25         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_EARPIECE),
26         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_SPEAKER),
27         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_SPEAKER_SAFE),
28         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_WIRED_HEADSET),
29         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_WIRED_HEADPHONE),
30         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_BLUETOOTH_SCO),
31         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET),
32         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT),
33         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_ALL_SCO),
34         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP),
35         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES),
36         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER),
37         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_ALL_A2DP),
38         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_AUX_DIGITAL),
39         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_HDMI),
40         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET),
41         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET),
42         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_USB_ACCESSORY),
43         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_USB_DEVICE),
44         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_ALL_USB),
45         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_REMOTE_SUBMIX),
46         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_TELEPHONY_TX),
47         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_LINE),
48         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_HDMI_ARC),
49         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_SPDIF),
50         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_FM),
51         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_AUX_LINE),
52         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_IP),
53         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_BUS),
54         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_STUB),
55         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_AMBIENT),
56         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_BUILTIN_MIC),
57         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET),
58         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_ALL_SCO),
59         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_WIRED_HEADSET),
60         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_AUX_DIGITAL),
61         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_HDMI),
62         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_TELEPHONY_RX),
63         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_VOICE_CALL),
64         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_BACK_MIC),
65         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_REMOTE_SUBMIX),
66         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET),
67         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET),
68         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_USB_ACCESSORY),
69         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_USB_DEVICE),
70         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_FM_TUNER),
71         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_TV_TUNER),
72         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_LINE),
73         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_SPDIF),
74         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_A2DP),
75         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_LOOPBACK),
76         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_IP),
77         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_BUS),
78         MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_STUB),
79 };
80 
81 template<>
82 const size_t DeviceConverter::mSize = sizeof(DeviceConverter::mTable) /
83         sizeof(DeviceConverter::mTable[0]);
84 
85 
86 template <>
87 const OutputFlagConverter::Table OutputFlagConverter::mTable[] = {
88     MAKE_STRING_FROM_ENUM(AUDIO_OUTPUT_FLAG_DIRECT),
89     MAKE_STRING_FROM_ENUM(AUDIO_OUTPUT_FLAG_PRIMARY),
90     MAKE_STRING_FROM_ENUM(AUDIO_OUTPUT_FLAG_FAST),
91     MAKE_STRING_FROM_ENUM(AUDIO_OUTPUT_FLAG_DEEP_BUFFER),
92     MAKE_STRING_FROM_ENUM(AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD),
93     MAKE_STRING_FROM_ENUM(AUDIO_OUTPUT_FLAG_NON_BLOCKING),
94     MAKE_STRING_FROM_ENUM(AUDIO_OUTPUT_FLAG_HW_AV_SYNC),
95     MAKE_STRING_FROM_ENUM(AUDIO_OUTPUT_FLAG_TTS),
96     MAKE_STRING_FROM_ENUM(AUDIO_OUTPUT_FLAG_RAW),
97     MAKE_STRING_FROM_ENUM(AUDIO_OUTPUT_FLAG_SYNC),
98 };
99 template<>
100 const size_t OutputFlagConverter::mSize = sizeof(OutputFlagConverter::mTable) /
101         sizeof(OutputFlagConverter::mTable[0]);
102 
103 
104 template <>
105 const InputFlagConverter::Table InputFlagConverter::mTable[] = {
106     MAKE_STRING_FROM_ENUM(AUDIO_INPUT_FLAG_FAST),
107     MAKE_STRING_FROM_ENUM(AUDIO_INPUT_FLAG_HW_HOTWORD),
108     MAKE_STRING_FROM_ENUM(AUDIO_INPUT_FLAG_RAW),
109     MAKE_STRING_FROM_ENUM(AUDIO_INPUT_FLAG_SYNC),
110 };
111 template<>
112 const size_t InputFlagConverter::mSize = sizeof(InputFlagConverter::mTable) /
113         sizeof(InputFlagConverter::mTable[0]);
114 
115 
116 template <>
117 const FormatConverter::Table FormatConverter::mTable[] = {
118     MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_PCM_16_BIT),
119     MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_PCM_8_BIT),
120     MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_PCM_32_BIT),
121     MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_PCM_8_24_BIT),
122     MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_PCM_FLOAT),
123     MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_PCM_24_BIT_PACKED),
124     MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_MP3),
125     MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_AAC),
126     MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_AAC_MAIN),
127     MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_AAC_LC),
128     MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_AAC_SSR),
129     MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_AAC_LTP),
130     MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_AAC_HE_V1),
131     MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_AAC_SCALABLE),
132     MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_AAC_ERLC),
133     MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_AAC_LD),
134     MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_AAC_HE_V2),
135     MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_AAC_ELD),
136     MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_VORBIS),
137     MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_HE_AAC_V1),
138     MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_HE_AAC_V2),
139     MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_OPUS),
140     MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_AC3),
141     MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_E_AC3),
142     MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_DTS),
143     MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_DTS_HD),
144     MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_IEC61937),
145 };
146 template<>
147 const size_t FormatConverter::mSize = sizeof(FormatConverter::mTable) /
148         sizeof(FormatConverter::mTable[0]);
149 
150 
151 template <>
152 const OutputChannelConverter::Table OutputChannelConverter::mTable[] = {
153     MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_OUT_MONO),
154     MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_OUT_STEREO),
155     MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_OUT_QUAD),
156     MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_OUT_5POINT1),
157     MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_OUT_7POINT1),
158 };
159 template<>
160 const size_t OutputChannelConverter::mSize = sizeof(OutputChannelConverter::mTable) /
161         sizeof(OutputChannelConverter::mTable[0]);
162 
163 
164 template <>
165 const InputChannelConverter::Table InputChannelConverter::mTable[] = {
166     MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_IN_MONO),
167     MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_IN_STEREO),
168     MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_IN_FRONT_BACK),
169 };
170 template<>
171 const size_t InputChannelConverter::mSize = sizeof(InputChannelConverter::mTable) /
172         sizeof(InputChannelConverter::mTable[0]);
173 
174 template <>
175 const ChannelIndexConverter::Table ChannelIndexConverter::mTable[] = {
176     {"AUDIO_CHANNEL_INDEX_MASK_1", static_cast<audio_channel_mask_t>(AUDIO_CHANNEL_INDEX_MASK_1)},
177     {"AUDIO_CHANNEL_INDEX_MASK_2", static_cast<audio_channel_mask_t>(AUDIO_CHANNEL_INDEX_MASK_2)},
178     {"AUDIO_CHANNEL_INDEX_MASK_3", static_cast<audio_channel_mask_t>(AUDIO_CHANNEL_INDEX_MASK_3)},
179     {"AUDIO_CHANNEL_INDEX_MASK_4", static_cast<audio_channel_mask_t>(AUDIO_CHANNEL_INDEX_MASK_4)},
180     {"AUDIO_CHANNEL_INDEX_MASK_5", static_cast<audio_channel_mask_t>(AUDIO_CHANNEL_INDEX_MASK_5)},
181     {"AUDIO_CHANNEL_INDEX_MASK_6", static_cast<audio_channel_mask_t>(AUDIO_CHANNEL_INDEX_MASK_6)},
182     {"AUDIO_CHANNEL_INDEX_MASK_7", static_cast<audio_channel_mask_t>(AUDIO_CHANNEL_INDEX_MASK_7)},
183     {"AUDIO_CHANNEL_INDEX_MASK_8", static_cast<audio_channel_mask_t>(AUDIO_CHANNEL_INDEX_MASK_8)},
184 };
185 template<>
186 const size_t ChannelIndexConverter::mSize = sizeof(ChannelIndexConverter::mTable) /
187         sizeof(ChannelIndexConverter::mTable[0]);
188 
189 
190 template <>
191 const GainModeConverter::Table GainModeConverter::mTable[] = {
192     MAKE_STRING_FROM_ENUM(AUDIO_GAIN_MODE_JOINT),
193     MAKE_STRING_FROM_ENUM(AUDIO_GAIN_MODE_CHANNELS),
194     MAKE_STRING_FROM_ENUM(AUDIO_GAIN_MODE_RAMP),
195 };
196 
197 template<>
198 const size_t GainModeConverter::mSize = sizeof(GainModeConverter::mTable) /
199         sizeof(GainModeConverter::mTable[0]);
200 
201 template <>
202 const DeviceCategoryConverter::Table DeviceCategoryConverter::mTable[] = {
203     MAKE_STRING_FROM_ENUM(DEVICE_CATEGORY_HEADSET),
204     MAKE_STRING_FROM_ENUM(DEVICE_CATEGORY_SPEAKER),
205     MAKE_STRING_FROM_ENUM(DEVICE_CATEGORY_EARPIECE),
206     MAKE_STRING_FROM_ENUM(DEVICE_CATEGORY_EXT_MEDIA)
207 };
208 
209 template<>
210 const size_t DeviceCategoryConverter::mSize = sizeof(DeviceCategoryConverter::mTable) /
211         sizeof(DeviceCategoryConverter::mTable[0]);
212 
213 template <>
214 const StreamTypeConverter::Table StreamTypeConverter::mTable[] = {
215     MAKE_STRING_FROM_ENUM(AUDIO_STREAM_VOICE_CALL),
216     MAKE_STRING_FROM_ENUM(AUDIO_STREAM_SYSTEM),
217     MAKE_STRING_FROM_ENUM(AUDIO_STREAM_RING),
218     MAKE_STRING_FROM_ENUM(AUDIO_STREAM_MUSIC),
219     MAKE_STRING_FROM_ENUM(AUDIO_STREAM_ALARM),
220     MAKE_STRING_FROM_ENUM(AUDIO_STREAM_NOTIFICATION),
221     MAKE_STRING_FROM_ENUM(AUDIO_STREAM_BLUETOOTH_SCO ),
222     MAKE_STRING_FROM_ENUM(AUDIO_STREAM_ENFORCED_AUDIBLE),
223     MAKE_STRING_FROM_ENUM(AUDIO_STREAM_DTMF),
224     MAKE_STRING_FROM_ENUM(AUDIO_STREAM_TTS),
225     MAKE_STRING_FROM_ENUM(AUDIO_STREAM_ACCESSIBILITY),
226     MAKE_STRING_FROM_ENUM(AUDIO_STREAM_REROUTING),
227     MAKE_STRING_FROM_ENUM(AUDIO_STREAM_PATCH),
228 };
229 
230 template<>
231 const size_t StreamTypeConverter::mSize = sizeof(StreamTypeConverter::mTable) /
232         sizeof(StreamTypeConverter::mTable[0]);
233 
234 template <class Traits>
toString(const typename Traits::Type & value,std::string & str)235 bool TypeConverter<Traits>::toString(const typename Traits::Type &value, std::string &str)
236 {
237     for (size_t i = 0; i < mSize; i++) {
238         if (mTable[i].value == value) {
239             str = mTable[i].literal;
240             return true;
241         }
242     }
243     return false;
244 }
245 
246 template <class Traits>
fromString(const std::string & str,typename Traits::Type & result)247 bool TypeConverter<Traits>::fromString(const std::string &str, typename Traits::Type &result)
248 {
249     for (size_t i = 0; i < mSize; i++) {
250         if (strcmp(mTable[i].literal, str.c_str()) == 0) {
251             ALOGV("stringToEnum() found %s", mTable[i].literal);
252             result = mTable[i].value;
253             return true;
254         }
255     }
256     return false;
257 }
258 
259 template <class Traits>
collectionFromString(const std::string & str,typename Traits::Collection & collection,const char * del)260 void TypeConverter<Traits>::collectionFromString(const std::string &str,
261                                                  typename Traits::Collection &collection,
262                                                  const char *del)
263 {
264     char *literal = strdup(str.c_str());
265 
266     for (const char *cstr = strtok(literal, del); cstr != NULL; cstr = strtok(NULL, del)) {
267         typename Traits::Type value;
268         if (fromString(cstr, value)) {
269             collection.add(value);
270         }
271     }
272     free(literal);
273 }
274 
275 template <class Traits>
maskFromString(const std::string & str,const char * del)276 uint32_t TypeConverter<Traits>::maskFromString(const std::string &str, const char *del)
277 {
278     char *literal = strdup(str.c_str());
279     uint32_t value = 0;
280     for (const char *cstr = strtok(literal, del); cstr != NULL; cstr = strtok(NULL, del)) {
281         typename Traits::Type type;
282         if (fromString(cstr, type)) {
283             value |= static_cast<uint32_t>(type);
284         }
285     }
286     free(literal);
287     return value;
288 }
289 
290 template class TypeConverter<DeviceTraits>;
291 template class TypeConverter<OutputFlagTraits>;
292 template class TypeConverter<InputFlagTraits>;
293 template class TypeConverter<FormatTraits>;
294 template class TypeConverter<OutputChannelTraits>;
295 template class TypeConverter<InputChannelTraits>;
296 template class TypeConverter<ChannelIndexTraits>;
297 template class TypeConverter<GainModeTraits>;
298 template class TypeConverter<StreamTraits>;
299 template class TypeConverter<DeviceCategoryTraits>;
300 
301 }; // namespace android
302 
303