• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "AudioTypes.h"
18 #include "StringUtils.h"
19 #include <media/TypeConverter.h> // requires libmedia_helper to get the Audio code.
20 
21 namespace android::mediametrics::types {
22 
getAudioCallerNameMap()23 const std::unordered_map<std::string, int32_t>& getAudioCallerNameMap() {
24     // DO NOT MODIFY VALUES (OK to add new ones).
25     // This may be found in frameworks/av/media/libmediametrics/include/MediaMetricsConstants.h
26     static std::unordered_map<std::string, int32_t> map{
27         {"unknown",       0},           // callerName not set
28         {"aaudio",        1},           // Native AAudio
29         {"java",          2},           // Java API layer
30         {"media",         3},           // libmedia (mediaplayer)
31         {"opensles",      4},           // Open SLES
32         {"rtp",           5},           // RTP communication
33         {"soundpool",     6},           // SoundPool
34         {"tonegenerator", 7},           // dial tones
35         // R values above.
36     };
37     return map;
38 }
39 
40 // A map in case we need to return a flag for input devices.
41 // This is 64 bits (and hence not the same as audio_device_t) because we need extra
42 // bits to represent new devices.
43 // NOT USED FOR R.  We do not use int64 flags.
44 // This can be out of date for now, as it is unused even for string validation
45 // (instead TypeConverter<InputDeviceTraits> is used).
getAudioDeviceInMap()46 const std::unordered_map<std::string, int64_t>& getAudioDeviceInMap() {
47     // DO NOT MODIFY VALUES (OK to add new ones).  This does NOT match audio_device_t.
48     static std::unordered_map<std::string, int64_t> map{
49         {"AUDIO_DEVICE_IN_COMMUNICATION",          1LL << 0},
50         {"AUDIO_DEVICE_IN_AMBIENT",                1LL << 1},
51         {"AUDIO_DEVICE_IN_BUILTIN_MIC",            1LL << 2},
52         {"AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET",  1LL << 3},
53         {"AUDIO_DEVICE_IN_WIRED_HEADSET",          1LL << 4},
54         {"AUDIO_DEVICE_IN_AUX_DIGITAL",            1LL << 5},
55         {"AUDIO_DEVICE_IN_HDMI",                   1LL << 5}, // HDMI == AUX_DIGITAL (6 reserved)
56         {"AUDIO_DEVICE_IN_VOICE_CALL",             1LL << 7},
57         {"AUDIO_DEVICE_IN_TELEPHONY_RX",           1LL << 7}, // TELEPHONY_RX == VOICE_CALL (8 reserved)
58         {"AUDIO_DEVICE_IN_BACK_MIC",               1LL << 9},
59         {"AUDIO_DEVICE_IN_REMOTE_SUBMIX",          1LL << 10},
60         {"AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET",      1LL << 11},
61         {"AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET",      1LL << 12},
62         {"AUDIO_DEVICE_IN_USB_ACCESSORY",          1LL << 13},
63         {"AUDIO_DEVICE_IN_USB_DEVICE",             1LL << 14},
64         {"AUDIO_DEVICE_IN_FM_TUNER",               1LL << 15},
65         {"AUDIO_DEVICE_IN_TV_TUNER",               1LL << 16},
66         {"AUDIO_DEVICE_IN_LINE",                   1LL << 17},
67         {"AUDIO_DEVICE_IN_SPDIF",                  1LL << 18},
68         {"AUDIO_DEVICE_IN_BLUETOOTH_A2DP",         1LL << 19},
69         {"AUDIO_DEVICE_IN_LOOPBACK",               1LL << 20},
70         {"AUDIO_DEVICE_IN_IP",                     1LL << 21},
71         {"AUDIO_DEVICE_IN_BUS",                    1LL << 22},
72         {"AUDIO_DEVICE_IN_PROXY",                  1LL << 23},
73         {"AUDIO_DEVICE_IN_USB_HEADSET",            1LL << 24},
74         {"AUDIO_DEVICE_IN_BLUETOOTH_BLE",          1LL << 25},
75         {"AUDIO_DEVICE_IN_HDMI_ARC",               1LL << 26},
76         {"AUDIO_DEVICE_IN_ECHO_REFERENCE",         1LL << 27},
77         {"AUDIO_DEVICE_IN_DEFAULT",                1LL << 28},
78         // R values above.
79         {"AUDIO_DEVICE_IN_BLE_HEADSET",            1LL << 29},
80         {"AUDIO_DEVICE_IN_HDMI_EARC",              1LL << 30},
81     };
82     return map;
83 }
84 
85 // A map in case we need to return a flag for output devices.
86 // This is 64 bits (and hence not the same as audio_device_t) because we need extra
87 // bits to represent new devices.
88 // NOT USED FOR R.  We do not use int64 flags.
89 // This can be out of date for now, as it is unused even for string validation
90 // (instead TypeConverter<OutputDeviceTraits> is used).
getAudioDeviceOutMap()91 const std::unordered_map<std::string, int64_t>& getAudioDeviceOutMap() {
92     // DO NOT MODIFY VALUES (OK to add new ones).  This does NOT match audio_device_t.
93     static std::unordered_map<std::string, int64_t> map{
94         {"AUDIO_DEVICE_OUT_EARPIECE",                  1LL << 0},
95         {"AUDIO_DEVICE_OUT_SPEAKER",                   1LL << 1},
96         {"AUDIO_DEVICE_OUT_WIRED_HEADSET",             1LL << 2},
97         {"AUDIO_DEVICE_OUT_WIRED_HEADPHONE",           1LL << 3},
98         {"AUDIO_DEVICE_OUT_BLUETOOTH_SCO",             1LL << 4},
99         {"AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET",     1LL << 5},
100         {"AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT",      1LL << 6},
101         {"AUDIO_DEVICE_OUT_BLUETOOTH_A2DP",            1LL << 7},
102         {"AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES", 1LL << 8},
103         {"AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER",    1LL << 9},
104         {"AUDIO_DEVICE_OUT_AUX_DIGITAL",               1LL << 10},
105         {"AUDIO_DEVICE_OUT_HDMI",                      1LL << 10}, // HDMI == AUX_DIGITAL (11 reserved)
106         {"AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET",         1LL << 12},
107         {"AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET",         1LL << 13},
108         {"AUDIO_DEVICE_OUT_USB_ACCESSORY",             1LL << 14},
109         {"AUDIO_DEVICE_OUT_USB_DEVICE",                1LL << 15},
110         {"AUDIO_DEVICE_OUT_REMOTE_SUBMIX",             1LL << 16},
111         {"AUDIO_DEVICE_OUT_TELEPHONY_TX",              1LL << 17},
112         {"AUDIO_DEVICE_OUT_LINE",                      1LL << 18},
113         {"AUDIO_DEVICE_OUT_HDMI_ARC",                  1LL << 19},
114         {"AUDIO_DEVICE_OUT_SPDIF",                     1LL << 20},
115         {"AUDIO_DEVICE_OUT_FM",                        1LL << 21},
116         {"AUDIO_DEVICE_OUT_AUX_LINE",                  1LL << 22},
117         {"AUDIO_DEVICE_OUT_SPEAKER_SAFE",              1LL << 23},
118         {"AUDIO_DEVICE_OUT_IP",                        1LL << 24},
119         {"AUDIO_DEVICE_OUT_BUS",                       1LL << 25},
120         {"AUDIO_DEVICE_OUT_PROXY",                     1LL << 26},
121         {"AUDIO_DEVICE_OUT_USB_HEADSET",               1LL << 27},
122         {"AUDIO_DEVICE_OUT_HEARING_AID",               1LL << 28},
123         {"AUDIO_DEVICE_OUT_ECHO_CANCELLER",            1LL << 29},
124         {"AUDIO_DEVICE_OUT_DEFAULT",                   1LL << 30},
125         // R values above.
126         {"AUDIO_DEVICE_OUT_BLE_HEADSET",               1LL << 31},
127         {"AUDIO_DEVICE_OUT_BLE_SPEAKER",               1LL << 32},
128         {"AUDIO_DEVICE_OUT_HDMI_EARC",                 1LL << 33},
129     };
130     return map;
131 }
132 
getAudioThreadTypeMap()133 const std::unordered_map<std::string, int32_t>& getAudioThreadTypeMap() {
134     // DO NOT MODIFY VALUES (OK to add new ones).
135     // This may be found in frameworks/av/services/audioflinger/Threads.h
136     static std::unordered_map<std::string, int32_t> map{
137         // UNKNOWN is -1
138         {"MIXER",         0},          // Thread class is MixerThread
139         {"DIRECT",        1},          // Thread class is DirectOutputThread
140         {"DUPLICATING",   2},          // Thread class is DuplicatingThread
141         {"RECORD",        3},          // Thread class is RecordThread
142         {"OFFLOAD",       4},          // Thread class is OffloadThread
143         {"MMAP_PLAYBACK", 5},          // Thread class for MMAP playback stream
144         {"MMAP_CAPTURE",  6},          // Thread class for MMAP capture stream
145         // R values above.
146     };
147     return map;
148 }
149 
getAudioTrackTraitsMap()150 const std::unordered_map<std::string, int32_t>& getAudioTrackTraitsMap() {
151     // DO NOT MODIFY VALUES (OK to add new ones).
152     static std::unordered_map<std::string, int32_t> map{
153         {"static",        (1 << 0)},  // A static track
154         // R values above.
155     };
156     return map;
157 }
158 
getAAudioDirection()159 const std::unordered_map<std::string, int32_t>& getAAudioDirection() {
160     // DO NOT MODIFY VALUES(OK to add new ones).
161     // This may be found in frameworks/av/media/libaaudio/include/aaudio/AAudio.h
162     static std::unordered_map<std::string, int32_t> map {
163         // UNKNOWN is 0
164         {"AAUDIO_DIRECTION_OUTPUT",    1 /* AAUDIO_DIRECTION_OUTPUT + 1 */},
165         {"AAUDIO_DIRECTION_INPUT",     2 /* AAUDIO_DIRECTION_INPUT + 1*/},
166     };
167     return map;
168 }
169 
getAAudioPerformanceMode()170 const std::unordered_map<std::string, int32_t>& getAAudioPerformanceMode() {
171     // DO NOT MODIFY VALUES(OK to add new ones).
172     // This may be found in frameworks/av/media/libaaudio/include/aaudio/AAudio.h
173     static std::unordered_map<std::string, int32_t> map {
174         // UNKNOWN is 0
175         {"AAUDIO_PERFORMANCE_MODE_NONE",            10},
176         {"AAUDIO_PERFORMANCE_MODE_POWER_SAVING",    11},
177         {"AAUDIO_PERFORMANCE_MODE_LOW_LATENCY",     12},
178     };
179     return map;
180 }
181 
getAAudioSharingMode()182 const std::unordered_map<std::string, int32_t>& getAAudioSharingMode() {
183     // DO NOT MODIFY VALUES(OK to add new ones).
184     // This may be found in frameworks/av/media/libaaudio/include/aaudio/AAudio.h
185     static std::unordered_map<std::string, int32_t> map {
186         // UNKNOWN is 0
187         {"AAUDIO_SHARING_MODE_EXCLUSIVE",    1 /* AAUDIO_SHARING_MODE_EXCLUSIVE + 1 */},
188         {"AAUDIO_SHARING_MODE_SHARED",       2 /* AAUDIO_SHARING_MODE_SHARED + 1 */},
189     };
190     return map;
191 }
192 
193 // Helper: Create the corresponding int32 from string flags split with '|'.
194 template <typename Traits>
int32FromFlags(const std::string & flags)195 int32_t int32FromFlags(const std::string &flags)
196 {
197     const auto result = stringutils::split(flags, "|");
198     int32_t intFlags = 0;
199     for (const auto& flag : result) {
200         typename Traits::Type value;
201         if (!TypeConverter<Traits>::fromString(flag, value)) {
202             break;
203         }
204         intFlags |= value;
205     }
206     return intFlags;
207 }
208 
209 template <typename Traits>
stringFromFlags(const std::string & flags,size_t len)210 std::string stringFromFlags(const std::string &flags, size_t len)
211 {
212     const auto result = stringutils::split(flags, "|");
213     std::string sFlags;
214     for (const auto& flag : result) {
215         typename Traits::Type value;
216         if (!TypeConverter<Traits>::fromString(flag, value)) {
217             break;
218         }
219         if (len >= flag.size()) continue;
220         if (!sFlags.empty()) sFlags += "|";
221         sFlags += flag.c_str() + len;
222     }
223     return sFlags;
224 }
225 
226 template <typename M>
validateStringFromMap(const std::string & str,const M & map)227 std::string validateStringFromMap(const std::string &str, const M& map)
228 {
229     if (str.empty()) return {};
230 
231     const auto result = stringutils::split(str, "|");
232     std::stringstream ss;
233     for (const auto &s : result) {
234         if (map.count(s) > 0) {
235             if (ss.tellp() > 0) ss << "|";
236             ss << s;
237         }
238     }
239     return ss.str();
240 }
241 
242 template <typename M>
flagsFromMap(const std::string & str,const M & map)243 typename M::mapped_type flagsFromMap(const std::string &str, const M& map)
244 {
245     if (str.empty()) return {};
246 
247     const auto result = stringutils::split(str, "|");
248     typename M::mapped_type value{};
249     for (const auto &s : result) {
250         auto it = map.find(s);
251         if (it == map.end()) continue;
252         value |= it->second;
253     }
254     return value;
255 }
256 
257 template <>
lookup(const std::string & contentType)258 int32_t lookup<CONTENT_TYPE>(const std::string &contentType)
259 {
260     AudioContentTraits::Type value;
261     if (!TypeConverter<AudioContentTraits>::fromString(contentType, value)) {
262         value = AUDIO_CONTENT_TYPE_UNKNOWN;
263     }
264     return (int32_t)value;
265 }
266 
267 template <>
lookup(const std::string & contentType)268 std::string lookup<CONTENT_TYPE>(const std::string &contentType)
269 {
270     AudioContentTraits::Type value;
271     if (!TypeConverter<AudioContentTraits>::fromString(contentType, value)) {
272         return "";
273     }
274     return contentType.c_str() + sizeof("AUDIO_CONTENT_TYPE");
275 }
276 
277 template <>
lookup(const std::string & encoding)278 int32_t lookup<ENCODING>(const std::string &encoding)
279 {
280     FormatTraits::Type value;
281     if (!TypeConverter<FormatTraits>::fromString(encoding, value)) {
282         value = AUDIO_FORMAT_INVALID;
283     }
284     return (int32_t)value;
285 }
286 
287 template <>
lookup(const std::string & encoding)288 std::string lookup<ENCODING>(const std::string &encoding)
289 {
290     FormatTraits::Type value;
291     if (!TypeConverter<FormatTraits>::fromString(encoding, value)) {
292         return "";
293     }
294     return encoding.c_str() + sizeof("AUDIO_FORMAT");
295 }
296 
297 template <>
lookup(const std::string & inputFlag)298 int32_t lookup<INPUT_FLAG>(const std::string &inputFlag)
299 {
300     return int32FromFlags<InputFlagTraits>(inputFlag);
301 }
302 
303 template <>
lookup(const std::string & inputFlag)304 std::string lookup<INPUT_FLAG>(const std::string &inputFlag)
305 {
306     return stringFromFlags<InputFlagTraits>(inputFlag, sizeof("AUDIO_INPUT_FLAG"));
307 }
308 
309 template <>
lookup(const std::string & outputFlag)310 int32_t lookup<OUTPUT_FLAG>(const std::string &outputFlag)
311 {
312     return int32FromFlags<OutputFlagTraits>(outputFlag);
313 }
314 
315 template <>
lookup(const std::string & outputFlag)316 std::string lookup<OUTPUT_FLAG>(const std::string &outputFlag)
317 {
318     return stringFromFlags<OutputFlagTraits>(outputFlag, sizeof("AUDIO_OUTPUT_FLAG"));
319 }
320 
321 template <>
lookup(const std::string & sourceType)322 int32_t lookup<SOURCE_TYPE>(const std::string &sourceType)
323 {
324     SourceTraits::Type value;
325     if (!TypeConverter<SourceTraits>::fromString(sourceType, value)) {
326         value = AUDIO_SOURCE_DEFAULT;
327     }
328     return (int32_t)value;
329 }
330 
331 template <>
lookup(const std::string & sourceType)332 std::string lookup<SOURCE_TYPE>(const std::string &sourceType)
333 {
334     SourceTraits::Type value;
335     if (!TypeConverter<SourceTraits>::fromString(sourceType, value)) {
336         return "";
337     }
338     return sourceType.c_str() + sizeof("AUDIO_SOURCE");
339 }
340 
341 template <>
lookup(const std::string & streamType)342 int32_t lookup<STREAM_TYPE>(const std::string &streamType)
343 {
344     StreamTraits::Type value;
345     if (!TypeConverter<StreamTraits>::fromString(streamType, value)) {
346         value = AUDIO_STREAM_DEFAULT;
347     }
348     return (int32_t)value;
349 }
350 
351 template <>
lookup(const std::string & streamType)352 std::string lookup<STREAM_TYPE>(const std::string &streamType)
353 {
354     StreamTraits::Type value;
355     if (!TypeConverter<StreamTraits>::fromString(streamType, value)) {
356         return "";
357     }
358     return streamType.c_str() + sizeof("AUDIO_STREAM");
359 }
360 
361 template <>
lookup(const std::string & usage)362 int32_t lookup<USAGE>(const std::string &usage)
363 {
364     UsageTraits::Type value;
365     if (!TypeConverter<UsageTraits>::fromString(usage, value)) {
366         value = AUDIO_USAGE_UNKNOWN;
367     }
368     return (int32_t)value;
369 }
370 
371 template <>
lookup(const std::string & usage)372 std::string lookup<USAGE>(const std::string &usage)
373 {
374     UsageTraits::Type value;
375     if (!TypeConverter<UsageTraits>::fromString(usage, value)) {
376         return "";
377     }
378     return usage.c_str() + sizeof("AUDIO_USAGE");
379 }
380 
381 template <>
lookup(const std::string & inputDevice)382 int64_t lookup<INPUT_DEVICE>(const std::string &inputDevice)
383 {
384     // NOT USED FOR R.
385     // Returns a set of bits, each one representing a device in inputDevice.
386     // This is a 64 bit integer, not the same as audio_device_t.
387     return flagsFromMap(inputDevice, getAudioDeviceInMap());
388 }
389 
390 template <>
lookup(const std::string & inputDevice)391 std::string lookup<INPUT_DEVICE>(const std::string &inputDevice)
392 {
393     return stringFromFlags<InputDeviceTraits>(inputDevice, sizeof("AUDIO_DEVICE_IN"));
394 }
395 
396 template <>
lookup(const std::string & outputDevice)397 int64_t lookup<OUTPUT_DEVICE>(const std::string &outputDevice)
398 {
399     // NOT USED FOR R.
400     // Returns a set of bits, each one representing a device in outputDevice.
401     // This is a 64 bit integer, not the same as audio_device_t.
402     return flagsFromMap(outputDevice, getAudioDeviceOutMap());
403 }
404 
405 template <>
lookup(const std::string & outputDevice)406 std::string lookup<OUTPUT_DEVICE>(const std::string &outputDevice)
407 {
408     return stringFromFlags<OutputDeviceTraits>(outputDevice, sizeof("AUDIO_DEVICE_OUT"));
409 }
410 
411 template <>
lookup(const std::string & callerName)412 int32_t lookup<CALLER_NAME>(const std::string &callerName)
413 {
414     auto& map = getAudioCallerNameMap();
415     auto it = map.find(callerName);
416     if (it == map.end()) {
417         return 0;      // return unknown
418     }
419     return it->second;
420 }
421 
422 template <>
lookup(const std::string & callerName)423 std::string lookup<CALLER_NAME>(const std::string &callerName)
424 {
425     auto& map = getAudioCallerNameMap();
426     auto it = map.find(callerName);
427     if (it == map.end()) {
428         return "";
429     }
430     return callerName;
431 }
432 
433 template <>
lookup(const std::string & threadType)434 int32_t lookup<THREAD_TYPE>(const std::string &threadType)
435 {
436     auto& map = getAudioThreadTypeMap();
437     auto it = map.find(threadType);
438     if (it == map.end()) {
439         return -1; // note this as an illegal thread value as we don't have unknown here.
440     }
441     return it->second;
442 }
443 
444 template <>
lookup(const std::string & threadType)445 std::string lookup<THREAD_TYPE>(const std::string &threadType)
446 {
447     auto& map = getAudioThreadTypeMap();
448     auto it = map.find(threadType);
449     if (it == map.end()) {
450         return "";
451     }
452     return threadType;
453 }
454 
isInputThreadType(const std::string & threadType)455 bool isInputThreadType(const std::string &threadType)
456 {
457     return threadType == "RECORD" || threadType == "MMAP_CAPTURE";
458 }
459 
460 template <>
lookup(const std::string & traits)461 std::string lookup<TRACK_TRAITS>(const std::string &traits)
462 {
463     return validateStringFromMap(traits, getAudioTrackTraitsMap());
464 }
465 
466 template <>
lookup(const std::string & traits)467 int32_t lookup<TRACK_TRAITS>(const std::string &traits)
468 {
469     return flagsFromMap(traits, getAudioTrackTraitsMap());
470 }
471 
472 template <>
lookup(const std::string & direction)473 std::string lookup<AAUDIO_DIRECTION>(const std::string &direction)
474 {
475     auto& map = getAAudioDirection();
476     auto it = map.find(direction);
477     if (it == map.end()) {
478         return "";
479     }
480     return direction;
481 }
482 
483 template <>
lookup(const std::string & direction)484 int32_t lookup<AAUDIO_DIRECTION>(const std::string &direction)
485 {
486     auto& map = getAAudioDirection();
487     auto it = map.find(direction);
488     if (it == map.end()) {
489         return 0; // return unknown
490     }
491     return it->second;
492 }
493 
494 template <>
lookup(const std::string & performanceMode)495 std::string lookup<AAUDIO_PERFORMANCE_MODE>(const std::string &performanceMode)
496 {
497     auto& map = getAAudioPerformanceMode();
498     auto it = map.find(performanceMode);
499     if (it == map.end()) {
500         return "";
501     }
502     return performanceMode;
503 }
504 
505 template <>
lookup(const std::string & performanceMode)506 int32_t lookup<AAUDIO_PERFORMANCE_MODE>(const std::string &performanceMode)
507 {
508     auto& map = getAAudioPerformanceMode();
509     auto it = map.find(performanceMode);
510     if (it == map.end()) {
511         return 0; // return unknown
512     }
513     return it->second;
514 }
515 
516 template <>
lookup(const std::string & sharingMode)517 std::string lookup<AAUDIO_SHARING_MODE>(const std::string &sharingMode)
518 {
519     auto& map = getAAudioSharingMode();
520     auto it = map.find(sharingMode);
521     if (it == map.end()) {
522         return "";
523     }
524     return sharingMode;
525 }
526 
527 template <>
lookup(const std::string & sharingMode)528 int32_t lookup<AAUDIO_SHARING_MODE>(const std::string &sharingMode)
529 {
530     auto& map = getAAudioSharingMode();
531     auto it = map.find(sharingMode);
532     if (it == map.end()) {
533         return 0; // return unknown
534     }
535     return it->second;
536 }
537 
538 } // namespace android::mediametrics::types
539