1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #ifndef AUDIO_DEVICE_INFO_H
16 #define AUDIO_DEVICE_INFO_H
17
18 #include <parcel.h>
19 #include <audio_stream_info.h>
20 #include <set>
21 #include <limits>
22
23 namespace OHOS {
24 namespace AudioStandard {
25 constexpr size_t AUDIO_DEVICE_INFO_SIZE_LIMIT = 30;
26 constexpr int32_t INVALID_GROUP_ID = -1;
27
28 enum API_VERSION {
29 API_7 = 7,
30 API_8,
31 API_9,
32 API_10,
33 API_11,
34 API_MAX = 1000
35 };
36
37 enum DeviceFlag {
38 /**
39 * Device flag none.
40 */
41 NONE_DEVICES_FLAG = 0,
42 /**
43 * Indicates all output audio devices.
44 */
45 OUTPUT_DEVICES_FLAG = 1,
46 /**
47 * Indicates all input audio devices.
48 */
49 INPUT_DEVICES_FLAG = 2,
50 /**
51 * Indicates all audio devices.
52 */
53 ALL_DEVICES_FLAG = 3,
54 /**
55 * Indicates all distributed output audio devices.
56 */
57 DISTRIBUTED_OUTPUT_DEVICES_FLAG = 4,
58 /**
59 * Indicates all distributed input audio devices.
60 */
61 DISTRIBUTED_INPUT_DEVICES_FLAG = 8,
62 /**
63 * Indicates all distributed audio devices.
64 */
65 ALL_DISTRIBUTED_DEVICES_FLAG = 12,
66 /**
67 * Indicates all local and distributed audio devices.
68 */
69 ALL_L_D_DEVICES_FLAG = 15,
70 /**
71 * Device flag max count.
72 */
73 DEVICE_FLAG_MAX
74 };
75
76 enum DeviceRole {
77 /**
78 * Device role none.
79 */
80 DEVICE_ROLE_NONE = -1,
81 /**
82 * Input device role.
83 */
84 INPUT_DEVICE = 1,
85 /**
86 * Output device role.
87 */
88 OUTPUT_DEVICE = 2,
89 /**
90 * Device role max count.
91 */
92 DEVICE_ROLE_MAX
93 };
94
95 enum DeviceType {
96 /**
97 * Indicates device type none.
98 */
99 DEVICE_TYPE_NONE = -1,
100 /**
101 * Indicates invalid device
102 */
103 DEVICE_TYPE_INVALID = 0,
104 /**
105 * Indicates a built-in earpiece device
106 */
107 DEVICE_TYPE_EARPIECE = 1,
108 /**
109 * Indicates a speaker built in a device.
110 */
111 DEVICE_TYPE_SPEAKER = 2,
112 /**
113 * Indicates a headset, which is the combination of a pair of headphones and a microphone.
114 */
115 DEVICE_TYPE_WIRED_HEADSET = 3,
116 /**
117 * Indicates a pair of wired headphones.
118 */
119 DEVICE_TYPE_WIRED_HEADPHONES = 4,
120 /**
121 * Indicates a Bluetooth device used for telephony.
122 */
123 DEVICE_TYPE_BLUETOOTH_SCO = 7,
124 /**
125 * Indicates a Bluetooth device supporting the Advanced Audio Distribution Profile (A2DP).
126 */
127 DEVICE_TYPE_BLUETOOTH_A2DP = 8,
128 /**
129 * Indicates a microphone built in a device.
130 */
131 DEVICE_TYPE_MIC = 15,
132 /**
133 * Indicates a microphone built in a device.
134 */
135 DEVICE_TYPE_WAKEUP = 16,
136 /**
137 * Indicates a microphone built in a device.
138 */
139 DEVICE_TYPE_USB_HEADSET = 22,
140 /**
141 * Indicates a usb-arm device.
142 */
143 DEVICE_TYPE_USB_ARM_HEADSET = 23,
144 /**
145 * Indicates a debug sink device
146 */
147 DEVICE_TYPE_FILE_SINK = 50,
148 /**
149 * Indicates a debug source device
150 */
151 DEVICE_TYPE_FILE_SOURCE = 51,
152 /**
153 * Indicates any headset/headphone for disconnect
154 */
155 DEVICE_TYPE_EXTERN_CABLE = 100,
156 /**
157 * Indicates default device
158 */
159 DEVICE_TYPE_DEFAULT = 1000,
160 /**
161 * Indicates device type max count.
162 */
163 DEVICE_TYPE_MAX
164 };
165
166 enum DeviceChangeType {
167 CONNECT = 0,
168 DISCONNECT = 1,
169 };
170
171 enum DeviceVolumeType {
172 EARPIECE_VOLUME_TYPE = 0,
173 SPEAKER_VOLUME_TYPE = 1,
174 HEADSET_VOLUME_TYPE = 2,
175 };
176
177 enum ActiveDeviceType {
178 ACTIVE_DEVICE_TYPE_NONE = -1,
179 EARPIECE = 1,
180 SPEAKER = 2,
181 BLUETOOTH_SCO = 7,
182 USB_HEADSET = 22,
183 FILE_SINK_DEVICE = 50,
184 ACTIVE_DEVICE_TYPE_MAX
185 };
186
187 enum CommunicationDeviceType {
188 /**
189 * Speaker.
190 * @since 7
191 * @syscap SystemCapability.Multimedia.Audio.Communication
192 */
193 COMMUNICATION_SPEAKER = 2
194 };
195
196 enum AudioDeviceManagerType {
197 DEV_MGR_UNKNOW = 0,
198 LOCAL_DEV_MGR,
199 REMOTE_DEV_MGR,
200 BLUETOOTH_DEV_MGR,
201 };
202
203 enum AudioDevicePrivacyType {
204 TYPE_PRIVACY,
205 TYPE_PUBLIC,
206 TYPE_NEGATIVE,
207 };
208
209 enum DeviceCategory {
210 CATEGORY_DEFAULT = 0,
211 BT_HEADPHONE = 1 << 0,
212 BT_SOUNDBOX = 1 << 1,
213 BT_CAR = 1 << 2,
214 BT_GLASSES = 1 << 3,
215 BT_WATCH = 1 << 4,
216 BT_HEARAID = 1 << 5,
217 BT_UNWEAR_HEADPHONE = 1 << 6,
218 };
219
220 enum DeviceUsage {
221 MEDIA = 1,
222 VOICE = 2,
223 ALL_USAGE,
224 };
225
226 enum DeviceInfoUpdateCommand {
227 CATEGORY_UPDATE = 1,
228 CONNECTSTATE_UPDATE,
229 ENABLE_UPDATE,
230 EXCEPTION_FLAG_UPDATE,
231 };
232
233 enum ConnectState {
234 CONNECTED,
235 SUSPEND_CONNECTED,
236 VIRTUAL_CONNECTED,
237 DEACTIVE_CONNECTED
238 };
239
240 struct DevicePrivacyInfo {
241 std::string deviceName;
242 DeviceType deviceType;
243 DeviceRole deviceRole;
244 DeviceCategory deviceCategory;
245 DeviceUsage deviceUsage;
246 };
247
MarshallingSetInt32(const std::set<T> & value,Parcel & parcel)248 template<typename T> bool MarshallingSetInt32(const std::set<T> &value, Parcel &parcel)
249 {
250 size_t size = value.size();
251 if (!parcel.WriteUint64(size)) {
252 return false;
253 }
254 for (const auto &i : value) {
255 if (!parcel.WriteInt32(i)) {
256 return false;
257 }
258 }
259 return true;
260 }
261
262 template<typename T> std::set<T> UnmarshallingSetInt32(Parcel &parcel,
263 const size_t maxSize = std::numeric_limits<size_t>::max())
264 {
265 size_t size = parcel.ReadUint64();
266 // due to security concerns, sizelimit has been imposed
267 if (size > maxSize) {
268 size = maxSize;
269 }
270
271 std::set<T> res;
272 for (size_t i = 0; i < size; i++) {
273 res.insert(static_cast<T>(parcel.ReadInt32()));
274 }
275 return res;
276 }
277
278 struct DeviceStreamInfo {
279 AudioEncodingType encoding = AudioEncodingType::ENCODING_PCM;
280 AudioSampleFormat format;
281 AudioChannelLayout channelLayout = AudioChannelLayout::CH_LAYOUT_UNKNOWN;
282 std::set<AudioSamplingRate> samplingRate;
283 std::set<AudioChannel> channels;
284
DeviceStreamInfoDeviceStreamInfo285 DeviceStreamInfo(AudioSamplingRate samplingRate_, AudioEncodingType encoding_, AudioSampleFormat format_,
286 AudioChannel channels_) : encoding(encoding_), format(format_),
287 samplingRate({samplingRate_}), channels({channels_})
288 {}
DeviceStreamInfoDeviceStreamInfo289 DeviceStreamInfo(AudioStreamInfo audioStreamInfo) : DeviceStreamInfo(audioStreamInfo.samplingRate,
290 audioStreamInfo.encoding, audioStreamInfo.format, audioStreamInfo.channels)
291 {}
292 DeviceStreamInfo() = default;
293
MarshallingDeviceStreamInfo294 bool Marshalling(Parcel &parcel) const
295 {
296 return parcel.WriteInt32(static_cast<int32_t>(encoding))
297 && parcel.WriteInt32(static_cast<int32_t>(format))
298 && MarshallingSetInt32(samplingRate, parcel)
299 && MarshallingSetInt32(channels, parcel);
300 }
UnmarshallingDeviceStreamInfo301 void Unmarshalling(Parcel &parcel)
302 {
303 encoding = static_cast<AudioEncodingType>(parcel.ReadInt32());
304 format = static_cast<AudioSampleFormat>(parcel.ReadInt32());
305 samplingRate = UnmarshallingSetInt32<AudioSamplingRate>(parcel, AUDIO_DEVICE_INFO_SIZE_LIMIT);
306 channels = UnmarshallingSetInt32<AudioChannel>(parcel, AUDIO_DEVICE_INFO_SIZE_LIMIT);
307 }
308
CheckParamsDeviceStreamInfo309 bool CheckParams()
310 {
311 if (samplingRate.size() == 0) {
312 return false;
313 }
314 if (channels.size() == 0) {
315 return false;
316 }
317 return true;
318 }
319 };
320
321 class DeviceInfo {
322 public:
323 DeviceType deviceType;
324 DeviceRole deviceRole;
325 int32_t deviceId;
326 int32_t channelMasks;
327 int32_t channelIndexMasks;
328 std::string deviceName;
329 std::string macAddress;
330 DeviceStreamInfo audioStreamInfo;
331 std::string networkId;
332 std::string displayName;
333 int32_t interruptGroupId;
334 int32_t volumeGroupId;
335 bool isLowLatencyDevice;
336 ConnectState connectState = CONNECTED;
337
338 DeviceInfo() = default;
339 ~DeviceInfo() = default;
Marshalling(Parcel & parcel)340 bool Marshalling(Parcel &parcel) const
341 {
342 return parcel.WriteInt32(static_cast<int32_t>(deviceType))
343 && parcel.WriteInt32(static_cast<int32_t>(deviceRole))
344 && parcel.WriteInt32(deviceId)
345 && parcel.WriteInt32(channelMasks)
346 && parcel.WriteInt32(channelIndexMasks)
347 && parcel.WriteString(deviceName)
348 && parcel.WriteString(macAddress)
349 && audioStreamInfo.Marshalling(parcel)
350 && parcel.WriteString(networkId)
351 && parcel.WriteString(displayName)
352 && parcel.WriteInt32(interruptGroupId)
353 && parcel.WriteInt32(volumeGroupId)
354 && parcel.WriteBool(isLowLatencyDevice);
355 }
Marshalling(Parcel & parcel,bool hasBTPermission,bool hasSystemPermission,int32_t apiVersion)356 bool Marshalling(Parcel &parcel, bool hasBTPermission, bool hasSystemPermission, int32_t apiVersion) const
357 {
358 DeviceType devType = deviceType;
359 int32_t devId = deviceId;
360 DeviceStreamInfo streamInfo = audioStreamInfo;
361
362 // If api target version < 11 && does not set deviceType, fix api compatibility.
363 if (apiVersion < API_11 && (deviceType == DEVICE_TYPE_NONE || deviceType == DEVICE_TYPE_INVALID)) {
364 // DeviceType use speaker or mic instead
365 if (deviceRole == OUTPUT_DEVICE) {
366 devType = DEVICE_TYPE_SPEAKER;
367 devId = 1; // 1 default speaker device id
368 } else if (deviceRole == INPUT_DEVICE) {
369 devType = DEVICE_TYPE_MIC;
370 devId = 2; // 2 default mic device id
371 }
372
373 //If does not set sampleRates use SAMPLE_RATE_44100 instead.
374 if (streamInfo.samplingRate.empty()) {
375 streamInfo.samplingRate.insert(SAMPLE_RATE_44100);
376 }
377 // If does not set channelCounts use STEREO instead.
378 if (streamInfo.channels.empty()) {
379 streamInfo.channels.insert(STEREO);
380 }
381 }
382
383 return parcel.WriteInt32(static_cast<int32_t>(devType))
384 && parcel.WriteInt32(static_cast<int32_t>(deviceRole))
385 && parcel.WriteInt32(devId)
386 && parcel.WriteInt32(channelMasks)
387 && parcel.WriteInt32(channelIndexMasks)
388 && parcel.WriteString((!hasBTPermission && (deviceType == DEVICE_TYPE_BLUETOOTH_A2DP
389 || deviceType == DEVICE_TYPE_BLUETOOTH_SCO)) ? "" : deviceName)
390 && parcel.WriteString((!hasBTPermission && (deviceType == DEVICE_TYPE_BLUETOOTH_A2DP
391 || deviceType == DEVICE_TYPE_BLUETOOTH_SCO)) ? "" : macAddress)
392 && streamInfo.Marshalling(parcel)
393 && parcel.WriteString(hasSystemPermission ? networkId : "")
394 && parcel.WriteString(displayName)
395 && parcel.WriteInt32(hasSystemPermission ? interruptGroupId : INVALID_GROUP_ID)
396 && parcel.WriteInt32(hasSystemPermission ? volumeGroupId : INVALID_GROUP_ID)
397 && parcel.WriteBool(isLowLatencyDevice);
398 }
Unmarshalling(Parcel & parcel)399 void Unmarshalling(Parcel &parcel)
400 {
401 deviceType = static_cast<DeviceType>(parcel.ReadInt32());
402 deviceRole = static_cast<DeviceRole>(parcel.ReadInt32());
403 deviceId = parcel.ReadInt32();
404 channelMasks = parcel.ReadInt32();
405 channelIndexMasks = parcel.ReadInt32();
406 deviceName = parcel.ReadString();
407 macAddress = parcel.ReadString();
408 audioStreamInfo.Unmarshalling(parcel);
409 networkId = parcel.ReadString();
410 displayName = parcel.ReadString();
411 interruptGroupId = parcel.ReadInt32();
412 volumeGroupId = parcel.ReadInt32();
413 isLowLatencyDevice = parcel.ReadBool();
414 }
415 };
416
417 enum class AudioStreamDeviceChangeReason {
418 UNKNOWN = 0,
419 NEW_DEVICE_AVAILABLE = 1,
420 OLD_DEVICE_UNAVALIABLE = 2,
421 OVERRODE = 3
422 };
423 } // namespace AudioStandard
424 } // namespace OHOS
425 #endif // AUDIO_DEVICE_INFO_H