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 #ifndef ANDROID_AUDIO_POLICY_CONFIGURATION_V7_0__ENUMS_H
18 #define ANDROID_AUDIO_POLICY_CONFIGURATION_V7_0__ENUMS_H
19 
20 #include <sys/types.h>
21 #include <regex>
22 #include <string>
23 
24 #include <android_audio_policy_configuration_V7_0_enums.h>
25 
26 namespace android::audio::policy::configuration::V7_0 {
27 
getChannelCount(AudioChannelMask mask)28 static inline size_t getChannelCount(AudioChannelMask mask) {
29     switch (mask) {
30         case AudioChannelMask::AUDIO_CHANNEL_NONE:
31             return 0;
32         case AudioChannelMask::AUDIO_CHANNEL_OUT_MONO:
33         case AudioChannelMask::AUDIO_CHANNEL_IN_MONO:
34         case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_1:
35             return 1;
36         case AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO:
37         case AudioChannelMask::AUDIO_CHANNEL_OUT_MONO_HAPTIC_A:
38         case AudioChannelMask::AUDIO_CHANNEL_OUT_HAPTIC_AB:
39         case AudioChannelMask::AUDIO_CHANNEL_IN_STEREO:
40         case AudioChannelMask::AUDIO_CHANNEL_IN_FRONT_BACK:
41         case AudioChannelMask::AUDIO_CHANNEL_IN_VOICE_UPLINK_MONO:
42         case AudioChannelMask::AUDIO_CHANNEL_IN_VOICE_DNLINK_MONO:
43         case AudioChannelMask::AUDIO_CHANNEL_IN_VOICE_CALL_MONO:
44         case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_2:
45             return 2;
46         case AudioChannelMask::AUDIO_CHANNEL_OUT_2POINT1:
47         case AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO_HAPTIC_A:
48         case AudioChannelMask::AUDIO_CHANNEL_OUT_MONO_HAPTIC_AB:
49         case AudioChannelMask::AUDIO_CHANNEL_OUT_TRI:
50         case AudioChannelMask::AUDIO_CHANNEL_OUT_TRI_BACK:
51         case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_3:
52             return 3;
53         case AudioChannelMask::AUDIO_CHANNEL_OUT_2POINT0POINT2:
54         case AudioChannelMask::AUDIO_CHANNEL_OUT_3POINT1:
55         case AudioChannelMask::AUDIO_CHANNEL_OUT_QUAD:
56         case AudioChannelMask::AUDIO_CHANNEL_OUT_QUAD_BACK:
57         case AudioChannelMask::AUDIO_CHANNEL_OUT_QUAD_SIDE:
58         case AudioChannelMask::AUDIO_CHANNEL_OUT_SURROUND:
59         case AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO_HAPTIC_AB:
60         case AudioChannelMask::AUDIO_CHANNEL_IN_2POINT0POINT2:
61         case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_4:
62             return 4;
63         case AudioChannelMask::AUDIO_CHANNEL_OUT_2POINT1POINT2:
64         case AudioChannelMask::AUDIO_CHANNEL_OUT_3POINT0POINT2:
65         case AudioChannelMask::AUDIO_CHANNEL_OUT_PENTA:
66         case AudioChannelMask::AUDIO_CHANNEL_IN_2POINT1POINT2:
67         case AudioChannelMask::AUDIO_CHANNEL_IN_3POINT0POINT2:
68         case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_5:
69             return 5;
70         case AudioChannelMask::AUDIO_CHANNEL_OUT_3POINT1POINT2:
71         case AudioChannelMask::AUDIO_CHANNEL_OUT_5POINT1:
72         case AudioChannelMask::AUDIO_CHANNEL_OUT_5POINT1_BACK:
73         case AudioChannelMask::AUDIO_CHANNEL_OUT_5POINT1_SIDE:
74         case AudioChannelMask::AUDIO_CHANNEL_IN_6:
75         case AudioChannelMask::AUDIO_CHANNEL_IN_3POINT1POINT2:
76         case AudioChannelMask::AUDIO_CHANNEL_IN_5POINT1:
77         case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_6:
78             return 6;
79         case AudioChannelMask::AUDIO_CHANNEL_OUT_6POINT1:
80         case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_7:
81             return 7;
82         case AudioChannelMask::AUDIO_CHANNEL_OUT_5POINT1POINT2:
83         case AudioChannelMask::AUDIO_CHANNEL_OUT_7POINT1:
84         case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_8:
85             return 8;
86         case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_9:
87             return 9;
88         case AudioChannelMask::AUDIO_CHANNEL_OUT_5POINT1POINT4:
89         case AudioChannelMask::AUDIO_CHANNEL_OUT_7POINT1POINT2:
90         case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_10:
91             return 10;
92         case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_11:
93             return 11;
94         case AudioChannelMask::AUDIO_CHANNEL_OUT_7POINT1POINT4:
95         case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_12:
96             return 12;
97         case AudioChannelMask::AUDIO_CHANNEL_OUT_13POINT_360RA:
98         case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_13:
99             return 13;
100         case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_14:
101             return 14;
102         case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_15:
103             return 15;
104         case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_16:
105             return 16;
106         case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_17:
107             return 17;
108         case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_18:
109             return 18;
110         case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_19:
111             return 19;
112         case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_20:
113             return 20;
114         case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_21:
115             return 21;
116         case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_22:
117             return 22;
118         case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_23:
119             return 23;
120         case AudioChannelMask::AUDIO_CHANNEL_OUT_22POINT2:
121         case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_24:
122             return 24;
123         case AudioChannelMask::UNKNOWN:
124             return 0;
125             // No default to make sure all cases are covered.
126     }
127     // This is to avoid undefined behavior if 'mask' isn't a valid enum value.
128     return 0;
129 }
130 
getChannelCount(const std::string & mask)131 static inline ssize_t getChannelCount(const std::string& mask) {
132     return getChannelCount(stringToAudioChannelMask(mask));
133 }
134 
isOutputDevice(AudioDevice device)135 static inline bool isOutputDevice(AudioDevice device) {
136     switch (device) {
137         case AudioDevice::UNKNOWN:
138         case AudioDevice::AUDIO_DEVICE_NONE:
139             return false;
140         case AudioDevice::AUDIO_DEVICE_OUT_EARPIECE:
141         case AudioDevice::AUDIO_DEVICE_OUT_SPEAKER:
142         case AudioDevice::AUDIO_DEVICE_OUT_WIRED_HEADSET:
143         case AudioDevice::AUDIO_DEVICE_OUT_WIRED_HEADPHONE:
144         case AudioDevice::AUDIO_DEVICE_OUT_BLUETOOTH_SCO:
145         case AudioDevice::AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET:
146         case AudioDevice::AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT:
147         case AudioDevice::AUDIO_DEVICE_OUT_BLUETOOTH_A2DP:
148         case AudioDevice::AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES:
149         case AudioDevice::AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER:
150         case AudioDevice::AUDIO_DEVICE_OUT_AUX_DIGITAL:
151         case AudioDevice::AUDIO_DEVICE_OUT_HDMI:
152         case AudioDevice::AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET:
153         case AudioDevice::AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET:
154         case AudioDevice::AUDIO_DEVICE_OUT_USB_ACCESSORY:
155         case AudioDevice::AUDIO_DEVICE_OUT_USB_DEVICE:
156         case AudioDevice::AUDIO_DEVICE_OUT_REMOTE_SUBMIX:
157         case AudioDevice::AUDIO_DEVICE_OUT_TELEPHONY_TX:
158         case AudioDevice::AUDIO_DEVICE_OUT_LINE:
159         case AudioDevice::AUDIO_DEVICE_OUT_HDMI_ARC:
160         case AudioDevice::AUDIO_DEVICE_OUT_HDMI_EARC:
161         case AudioDevice::AUDIO_DEVICE_OUT_SPDIF:
162         case AudioDevice::AUDIO_DEVICE_OUT_FM:
163         case AudioDevice::AUDIO_DEVICE_OUT_AUX_LINE:
164         case AudioDevice::AUDIO_DEVICE_OUT_SPEAKER_SAFE:
165         case AudioDevice::AUDIO_DEVICE_OUT_IP:
166         case AudioDevice::AUDIO_DEVICE_OUT_BUS:
167         case AudioDevice::AUDIO_DEVICE_OUT_PROXY:
168         case AudioDevice::AUDIO_DEVICE_OUT_USB_HEADSET:
169         case AudioDevice::AUDIO_DEVICE_OUT_HEARING_AID:
170         case AudioDevice::AUDIO_DEVICE_OUT_ECHO_CANCELLER:
171         case AudioDevice::AUDIO_DEVICE_OUT_BLE_HEADSET:
172         case AudioDevice::AUDIO_DEVICE_OUT_BLE_SPEAKER:
173         case AudioDevice::AUDIO_DEVICE_OUT_DEFAULT:
174         case AudioDevice::AUDIO_DEVICE_OUT_STUB:
175             return true;
176         case AudioDevice::AUDIO_DEVICE_IN_COMMUNICATION:
177         case AudioDevice::AUDIO_DEVICE_IN_AMBIENT:
178         case AudioDevice::AUDIO_DEVICE_IN_BUILTIN_MIC:
179         case AudioDevice::AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET:
180         case AudioDevice::AUDIO_DEVICE_IN_WIRED_HEADSET:
181         case AudioDevice::AUDIO_DEVICE_IN_AUX_DIGITAL:
182         case AudioDevice::AUDIO_DEVICE_IN_HDMI:
183         case AudioDevice::AUDIO_DEVICE_IN_VOICE_CALL:
184         case AudioDevice::AUDIO_DEVICE_IN_TELEPHONY_RX:
185         case AudioDevice::AUDIO_DEVICE_IN_BACK_MIC:
186         case AudioDevice::AUDIO_DEVICE_IN_REMOTE_SUBMIX:
187         case AudioDevice::AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET:
188         case AudioDevice::AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET:
189         case AudioDevice::AUDIO_DEVICE_IN_USB_ACCESSORY:
190         case AudioDevice::AUDIO_DEVICE_IN_USB_DEVICE:
191         case AudioDevice::AUDIO_DEVICE_IN_FM_TUNER:
192         case AudioDevice::AUDIO_DEVICE_IN_TV_TUNER:
193         case AudioDevice::AUDIO_DEVICE_IN_LINE:
194         case AudioDevice::AUDIO_DEVICE_IN_SPDIF:
195         case AudioDevice::AUDIO_DEVICE_IN_BLUETOOTH_A2DP:
196         case AudioDevice::AUDIO_DEVICE_IN_LOOPBACK:
197         case AudioDevice::AUDIO_DEVICE_IN_IP:
198         case AudioDevice::AUDIO_DEVICE_IN_BUS:
199         case AudioDevice::AUDIO_DEVICE_IN_PROXY:
200         case AudioDevice::AUDIO_DEVICE_IN_USB_HEADSET:
201         case AudioDevice::AUDIO_DEVICE_IN_BLUETOOTH_BLE:
202         case AudioDevice::AUDIO_DEVICE_IN_HDMI_ARC:
203         case AudioDevice::AUDIO_DEVICE_IN_HDMI_EARC:
204         case AudioDevice::AUDIO_DEVICE_IN_ECHO_REFERENCE:
205         case AudioDevice::AUDIO_DEVICE_IN_BLE_HEADSET:
206         case AudioDevice::AUDIO_DEVICE_IN_DEFAULT:
207         case AudioDevice::AUDIO_DEVICE_IN_STUB:
208             return false;
209             // No default to make sure all cases are covered.
210     }
211     // This is to avoid undefined behavior if 'device' isn't a valid enum value.
212     return false;
213 }
214 
isOutputDevice(const std::string & device)215 static inline bool isOutputDevice(const std::string& device) {
216     return isOutputDevice(stringToAudioDevice(device));
217 }
218 
isTelephonyDevice(AudioDevice device)219 static inline bool isTelephonyDevice(AudioDevice device) {
220     return device == AudioDevice::AUDIO_DEVICE_OUT_TELEPHONY_TX ||
221            device == AudioDevice::AUDIO_DEVICE_IN_TELEPHONY_RX;
222 }
223 
isTelephonyDevice(const std::string & device)224 static inline bool isTelephonyDevice(const std::string& device) {
225     return isTelephonyDevice(stringToAudioDevice(device));
226 }
227 
maybeVendorExtension(const std::string & s)228 static inline bool maybeVendorExtension(const std::string& s) {
229     // Only checks whether the string starts with the "vendor prefix".
230     static const std::string vendorPrefix = "VX_";
231     return s.size() > vendorPrefix.size() && s.substr(0, vendorPrefix.size()) == vendorPrefix;
232 }
233 
isVendorExtension(const std::string & s)234 static inline bool isVendorExtension(const std::string& s) {
235     // Must be the same as the "vendorExtension" rule from the XSD file.
236     static const std::regex vendorExtension("VX_[A-Z0-9]{3,}_[_A-Z0-9]+");
237     return std::regex_match(s.begin(), s.end(), vendorExtension);
238 }
239 
isUnknownAudioChannelMask(const std::string & mask)240 static inline bool isUnknownAudioChannelMask(const std::string& mask) {
241     return stringToAudioChannelMask(mask) == AudioChannelMask::UNKNOWN;
242 }
243 
isUnknownAudioContentType(const std::string & contentType)244 static inline bool isUnknownAudioContentType(const std::string& contentType) {
245     return stringToAudioContentType(contentType) == AudioContentType::UNKNOWN;
246 }
247 
isUnknownAudioDevice(const std::string & device)248 static inline bool isUnknownAudioDevice(const std::string& device) {
249     return stringToAudioDevice(device) == AudioDevice::UNKNOWN && !isVendorExtension(device);
250 }
251 
isUnknownAudioFormat(const std::string & format)252 static inline bool isUnknownAudioFormat(const std::string& format) {
253     return stringToAudioFormat(format) == AudioFormat::UNKNOWN && !isVendorExtension(format);
254 }
255 
isUnknownAudioGainMode(const std::string & mode)256 static inline bool isUnknownAudioGainMode(const std::string& mode) {
257     return stringToAudioGainMode(mode) == AudioGainMode::UNKNOWN;
258 }
259 
isUnknownAudioInOutFlag(const std::string & flag)260 static inline bool isUnknownAudioInOutFlag(const std::string& flag) {
261     return stringToAudioInOutFlag(flag) == AudioInOutFlag::UNKNOWN;
262 }
263 
isUnknownAudioSource(const std::string & source)264 static inline bool isUnknownAudioSource(const std::string& source) {
265     return stringToAudioSource(source) == AudioSource::UNKNOWN;
266 }
267 
isUnknownAudioStreamType(const std::string & streamType)268 static inline bool isUnknownAudioStreamType(const std::string& streamType) {
269     return stringToAudioStreamType(streamType) == AudioStreamType::UNKNOWN;
270 }
271 
isUnknownAudioUsage(const std::string & usage)272 static inline bool isUnknownAudioUsage(const std::string& usage) {
273     return stringToAudioUsage(usage) == AudioUsage::UNKNOWN;
274 }
275 
isLinearPcm(AudioFormat format)276 static inline bool isLinearPcm(AudioFormat format) {
277     switch (format) {
278         case AudioFormat::AUDIO_FORMAT_PCM_16_BIT:
279         case AudioFormat::AUDIO_FORMAT_PCM_8_BIT:
280         case AudioFormat::AUDIO_FORMAT_PCM_32_BIT:
281         case AudioFormat::AUDIO_FORMAT_PCM_8_24_BIT:
282         case AudioFormat::AUDIO_FORMAT_PCM_FLOAT:
283         case AudioFormat::AUDIO_FORMAT_PCM_24_BIT_PACKED:
284             return true;
285         default:
286             return false;
287     }
288 }
289 
isLinearPcm(const std::string & format)290 static inline bool isLinearPcm(const std::string& format) {
291     return isLinearPcm(stringToAudioFormat(format));
292 }
293 
isUnknownAudioEncapsulationType(const std::string & encapsulationType)294 static inline bool isUnknownAudioEncapsulationType(const std::string& encapsulationType) {
295     return stringToAudioEncapsulationType(encapsulationType) == AudioEncapsulationType::UNKNOWN;
296 }
297 
298 }  // namespace android::audio::policy::configuration::V7_0
299 
300 #endif  // ANDROID_AUDIO_POLICY_CONFIGURATION_V7_0__ENUMS_H
301