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 #include <unordered_set>
23
24 namespace OHOS {
25 namespace AudioStandard {
26 constexpr size_t AUDIO_DEVICE_INFO_SIZE_LIMIT = 30;
27 constexpr int32_t INVALID_GROUP_ID = -1;
28
29 const std::string LOCAL_NETWORK_ID = "LocalDevice";
30 const std::string REMOTE_NETWORK_ID = "RemoteDevice";
31
32 enum API_VERSION {
33 API_7 = 7,
34 API_8,
35 API_9,
36 API_10,
37 API_11,
38 API_MAX = 1000
39 };
40
41 enum DeviceFlag {
42 /**
43 * Device flag none.
44 */
45 NONE_DEVICES_FLAG = 0,
46 /**
47 * Indicates all output audio devices.
48 */
49 OUTPUT_DEVICES_FLAG = 1,
50 /**
51 * Indicates all input audio devices.
52 */
53 INPUT_DEVICES_FLAG = 2,
54 /**
55 * Indicates all audio devices.
56 */
57 ALL_DEVICES_FLAG = 3,
58 /**
59 * Indicates all distributed output audio devices.
60 */
61 DISTRIBUTED_OUTPUT_DEVICES_FLAG = 4,
62 /**
63 * Indicates all distributed input audio devices.
64 */
65 DISTRIBUTED_INPUT_DEVICES_FLAG = 8,
66 /**
67 * Indicates all distributed audio devices.
68 */
69 ALL_DISTRIBUTED_DEVICES_FLAG = 12,
70 /**
71 * Indicates all local and distributed audio devices.
72 */
73 ALL_L_D_DEVICES_FLAG = 15,
74 /**
75 * Device flag max count.
76 */
77 DEVICE_FLAG_MAX
78 };
79
80 enum DeviceRole {
81 /**
82 * Device role none.
83 */
84 DEVICE_ROLE_NONE = -1,
85 /**
86 * Input device role.
87 */
88 INPUT_DEVICE = 1,
89 /**
90 * Output device role.
91 */
92 OUTPUT_DEVICE = 2,
93 /**
94 * Device role max count.
95 */
96 DEVICE_ROLE_MAX
97 };
98
99 enum DeviceType {
100 /**
101 * Indicates device type none.
102 */
103 DEVICE_TYPE_NONE = -1,
104 /**
105 * Indicates invalid device
106 */
107 DEVICE_TYPE_INVALID = 0,
108 /**
109 * Indicates a built-in earpiece device
110 */
111 DEVICE_TYPE_EARPIECE = 1,
112 /**
113 * Indicates a speaker built in a device.
114 */
115 DEVICE_TYPE_SPEAKER = 2,
116 /**
117 * Indicates a headset, which is the combination of a pair of headphones and a microphone.
118 */
119 DEVICE_TYPE_WIRED_HEADSET = 3,
120 /**
121 * Indicates a pair of wired headphones.
122 */
123 DEVICE_TYPE_WIRED_HEADPHONES = 4,
124 /**
125 * Indicates a Bluetooth device used for telephony.
126 */
127 DEVICE_TYPE_BLUETOOTH_SCO = 7,
128 /**
129 * Indicates a Bluetooth device supporting the Advanced Audio Distribution Profile (A2DP).
130 */
131 DEVICE_TYPE_BLUETOOTH_A2DP = 8,
132 /**
133 * Indicates a microphone built in a device.
134 */
135 DEVICE_TYPE_MIC = 15,
136 /**
137 * Indicates a microphone built in a device.
138 */
139 DEVICE_TYPE_WAKEUP = 16,
140 /**
141 * Indicates a microphone built in a device.
142 */
143 DEVICE_TYPE_USB_HEADSET = 22,
144 /**
145 * Indicates a display device.
146 */
147 DEVICE_TYPE_DP = 23,
148 /**
149 * Indicates a virtual remote cast device
150 */
151 DEVICE_TYPE_REMOTE_CAST = 24,
152 /**
153 * Indicates a debug sink device
154 */
155 DEVICE_TYPE_FILE_SINK = 50,
156 /**
157 * Indicates a debug source device
158 */
159 DEVICE_TYPE_FILE_SOURCE = 51,
160 /**
161 * Indicates any headset/headphone for disconnect
162 */
163 DEVICE_TYPE_EXTERN_CABLE = 100,
164 /**
165 * Indicates default device
166 */
167 DEVICE_TYPE_DEFAULT = 1000,
168 /**
169 * Indicates a usb-arm device.
170 */
171 DEVICE_TYPE_USB_ARM_HEADSET = 1001,
172 /**
173 * Indicates device type max count.
174 */
175 DEVICE_TYPE_MAX
176 };
177
178 inline const std::unordered_set<DeviceType> INPUT_DEVICE_TYPE_SET = {
179 DeviceType::DEVICE_TYPE_WIRED_HEADSET,
180 DeviceType::DEVICE_TYPE_BLUETOOTH_SCO,
181 DeviceType::DEVICE_TYPE_MIC,
182 DeviceType::DEVICE_TYPE_WAKEUP,
183 DeviceType::DEVICE_TYPE_USB_HEADSET,
184 DeviceType::DEVICE_TYPE_USB_ARM_HEADSET,
185 DeviceType::DEVICE_TYPE_FILE_SOURCE,
186 };
187
IsInputDevice(DeviceType deviceType)188 inline bool IsInputDevice(DeviceType deviceType)
189 {
190 return INPUT_DEVICE_TYPE_SET.count(deviceType) > 0;
191 }
192
IsInputDevice(DeviceType deviceType,DeviceRole deviceRole)193 inline bool IsInputDevice(DeviceType deviceType, DeviceRole deviceRole)
194 {
195 // Arm usb device distinguishes input and output through device roles.
196 if (deviceType == DEVICE_TYPE_USB_ARM_HEADSET) {
197 return deviceRole == INPUT_DEVICE || deviceRole == DEVICE_ROLE_MAX;
198 } else {
199 return INPUT_DEVICE_TYPE_SET.count(deviceType) > 0;
200 }
201 }
202
203 inline const std::unordered_set<DeviceType> OUTPUT_DEVICE_TYPE_SET = {
204 DeviceType::DEVICE_TYPE_EARPIECE,
205 DeviceType::DEVICE_TYPE_SPEAKER,
206 DeviceType::DEVICE_TYPE_WIRED_HEADSET,
207 DeviceType::DEVICE_TYPE_WIRED_HEADPHONES,
208 DeviceType::DEVICE_TYPE_BLUETOOTH_SCO,
209 DeviceType::DEVICE_TYPE_BLUETOOTH_A2DP,
210 DeviceType::DEVICE_TYPE_USB_HEADSET,
211 DeviceType::DEVICE_TYPE_DP,
212 DeviceType::DEVICE_TYPE_USB_ARM_HEADSET,
213 DeviceType::DEVICE_TYPE_FILE_SINK,
214 DeviceType::DEVICE_TYPE_REMOTE_CAST,
215 };
216
IsOutputDevice(DeviceType deviceType)217 inline bool IsOutputDevice(DeviceType deviceType)
218 {
219 return OUTPUT_DEVICE_TYPE_SET.count(deviceType) > 0;
220 }
221
IsOutputDevice(DeviceType deviceType,DeviceRole deviceRole)222 inline bool IsOutputDevice(DeviceType deviceType, DeviceRole deviceRole)
223 {
224 // Arm usb device distinguishes input and output through device roles.
225 if (deviceType == DEVICE_TYPE_USB_ARM_HEADSET) {
226 return deviceRole == OUTPUT_DEVICE || deviceRole == DEVICE_ROLE_MAX;
227 } else {
228 return OUTPUT_DEVICE_TYPE_SET.count(deviceType) > 0;
229 }
230 }
231
232 enum DeviceBlockStatus {
233 DEVICE_UNBLOCKED = 0,
234 DEVICE_BLOCKED = 1,
235 };
236
237 enum DeviceChangeType {
238 CONNECT = 0,
239 DISCONNECT = 1,
240 };
241
242 enum DeviceVolumeType {
243 EARPIECE_VOLUME_TYPE = 0,
244 SPEAKER_VOLUME_TYPE = 1,
245 HEADSET_VOLUME_TYPE = 2,
246 };
247
248 enum ActiveDeviceType {
249 ACTIVE_DEVICE_TYPE_NONE = -1,
250 EARPIECE = 1,
251 SPEAKER = 2,
252 BLUETOOTH_SCO = 7,
253 USB_HEADSET = 22,
254 FILE_SINK_DEVICE = 50,
255 ACTIVE_DEVICE_TYPE_MAX
256 };
257
258 enum CommunicationDeviceType {
259 /**
260 * Speaker.
261 * @since 7
262 * @syscap SystemCapability.Multimedia.Audio.Communication
263 */
264 COMMUNICATION_SPEAKER = 2
265 };
266
267 enum AudioDeviceManagerType {
268 DEV_MGR_UNKNOW = 0,
269 LOCAL_DEV_MGR,
270 REMOTE_DEV_MGR,
271 BLUETOOTH_DEV_MGR,
272 };
273
274 enum AudioDevicePrivacyType {
275 TYPE_PRIVACY,
276 TYPE_PUBLIC,
277 TYPE_NEGATIVE,
278 };
279
280 enum DeviceCategory {
281 CATEGORY_DEFAULT = 0,
282 BT_HEADPHONE = 1 << 0,
283 BT_SOUNDBOX = 1 << 1,
284 BT_CAR = 1 << 2,
285 BT_GLASSES = 1 << 3,
286 BT_WATCH = 1 << 4,
287 BT_HEARAID = 1 << 5,
288 BT_UNWEAR_HEADPHONE = 1 << 6,
289 };
290
291 enum DeviceUsage {
292 MEDIA = 1 << 0,
293 VOICE = 1 << 1,
294 RECOGNITION = 1 << 2,
295 ALL_USAGE = (1 << 3) - 1, // Represents the bitwise OR of all the above usages.
296 };
297
298 enum DeviceInfoUpdateCommand {
299 CATEGORY_UPDATE = 1,
300 CONNECTSTATE_UPDATE,
301 ENABLE_UPDATE,
302 EXCEPTION_FLAG_UPDATE,
303 };
304
305 enum ConnectState {
306 CONNECTED,
307 SUSPEND_CONNECTED,
308 VIRTUAL_CONNECTED,
309 DEACTIVE_CONNECTED
310 };
311
312 enum PreferredType {
313 AUDIO_MEDIA_RENDER = 0,
314 AUDIO_CALL_RENDER = 1,
315 AUDIO_CALL_CAPTURE = 2,
316 AUDIO_RING_RENDER = 3,
317 AUDIO_RECORD_CAPTURE = 4,
318 AUDIO_TONE_RENDER = 5,
319 };
320
321 enum BluetoothOffloadState {
322 NO_A2DP_DEVICE = 0,
323 A2DP_NOT_OFFLOAD = 1,
324 A2DP_OFFLOAD = 2,
325 };
326
327 struct DevicePrivacyInfo {
328 std::string deviceName;
329 DeviceType deviceType;
330 DeviceRole deviceRole;
331 DeviceCategory deviceCategory;
332 DeviceUsage deviceUsage;
333 };
334
MarshallingSetInt32(const std::set<T> & value,Parcel & parcel)335 template<typename T> bool MarshallingSetInt32(const std::set<T> &value, Parcel &parcel)
336 {
337 size_t size = value.size();
338 if (!parcel.WriteUint64(size)) {
339 return false;
340 }
341 for (const auto &i : value) {
342 if (!parcel.WriteInt32(i)) {
343 return false;
344 }
345 }
346 return true;
347 }
348
349 template<typename T> std::set<T> UnmarshallingSetInt32(Parcel &parcel,
350 const size_t maxSize = std::numeric_limits<size_t>::max())
351 {
352 size_t size = parcel.ReadUint64();
353 // due to security concerns, sizelimit has been imposed
354 if (size > maxSize) {
355 size = maxSize;
356 }
357
358 std::set<T> res;
359 for (size_t i = 0; i < size; i++) {
360 res.insert(static_cast<T>(parcel.ReadInt32()));
361 }
362 return res;
363 }
364
365 struct DeviceStreamInfo {
366 AudioEncodingType encoding = AudioEncodingType::ENCODING_PCM;
367 AudioSampleFormat format = AudioSampleFormat::INVALID_WIDTH;
368 AudioChannelLayout channelLayout = AudioChannelLayout::CH_LAYOUT_UNKNOWN;
369 std::set<AudioSamplingRate> samplingRate;
370 std::set<AudioChannel> channels;
371
DeviceStreamInfoDeviceStreamInfo372 DeviceStreamInfo(AudioSamplingRate samplingRate_, AudioEncodingType encoding_, AudioSampleFormat format_,
373 AudioChannel channels_) : encoding(encoding_), format(format_),
374 samplingRate({samplingRate_}), channels({channels_})
375 {}
DeviceStreamInfoDeviceStreamInfo376 DeviceStreamInfo(AudioStreamInfo audioStreamInfo) : DeviceStreamInfo(audioStreamInfo.samplingRate,
377 audioStreamInfo.encoding, audioStreamInfo.format, audioStreamInfo.channels)
378 {}
379 DeviceStreamInfo() = default;
380
MarshallingDeviceStreamInfo381 bool Marshalling(Parcel &parcel) const
382 {
383 return parcel.WriteInt32(static_cast<int32_t>(encoding))
384 && parcel.WriteInt32(static_cast<int32_t>(format))
385 && MarshallingSetInt32(samplingRate, parcel)
386 && MarshallingSetInt32(channels, parcel);
387 }
UnmarshallingDeviceStreamInfo388 void Unmarshalling(Parcel &parcel)
389 {
390 encoding = static_cast<AudioEncodingType>(parcel.ReadInt32());
391 format = static_cast<AudioSampleFormat>(parcel.ReadInt32());
392 samplingRate = UnmarshallingSetInt32<AudioSamplingRate>(parcel, AUDIO_DEVICE_INFO_SIZE_LIMIT);
393 channels = UnmarshallingSetInt32<AudioChannel>(parcel, AUDIO_DEVICE_INFO_SIZE_LIMIT);
394 }
395
CheckParamsDeviceStreamInfo396 bool CheckParams()
397 {
398 if (samplingRate.size() == 0) {
399 return false;
400 }
401 if (channels.size() == 0) {
402 return false;
403 }
404 return true;
405 }
406 };
407
408 class DeviceInfo {
409 public:
410 DeviceType deviceType = DEVICE_TYPE_INVALID;
411 DeviceRole deviceRole = DEVICE_ROLE_NONE;
412 int32_t deviceId = -1;
413 int32_t channelMasks = 0;
414 int32_t channelIndexMasks = 0;
415 std::string deviceName = "";
416 std::string macAddress = "";
417 DeviceStreamInfo audioStreamInfo;
418 std::string networkId = LOCAL_NETWORK_ID;
419 std::string displayName = "";
420 int32_t interruptGroupId = 0;
421 int32_t volumeGroupId = 0;
422 bool isLowLatencyDevice = false;
423 int32_t a2dpOffloadFlag = NO_A2DP_DEVICE;
424 ConnectState connectState = CONNECTED;
425 DeviceCategory deviceCategory = CATEGORY_DEFAULT;
426
427 DeviceInfo() = default;
428 ~DeviceInfo() = default;
Marshalling(Parcel & parcel)429 bool Marshalling(Parcel &parcel) const
430 {
431 return parcel.WriteInt32(static_cast<int32_t>(deviceType))
432 && parcel.WriteInt32(static_cast<int32_t>(deviceRole))
433 && parcel.WriteInt32(deviceId)
434 && parcel.WriteInt32(channelMasks)
435 && parcel.WriteInt32(channelIndexMasks)
436 && parcel.WriteString(deviceName)
437 && parcel.WriteString(macAddress)
438 && audioStreamInfo.Marshalling(parcel)
439 && parcel.WriteString(networkId)
440 && parcel.WriteString(displayName)
441 && parcel.WriteInt32(interruptGroupId)
442 && parcel.WriteInt32(volumeGroupId)
443 && parcel.WriteBool(isLowLatencyDevice)
444 && parcel.WriteInt32(a2dpOffloadFlag)
445 && parcel.WriteInt32(static_cast<int32_t>(deviceCategory));
446 }
Marshalling(Parcel & parcel,bool hasBTPermission,bool hasSystemPermission,int32_t apiVersion)447 bool Marshalling(Parcel &parcel, bool hasBTPermission, bool hasSystemPermission, int32_t apiVersion) const
448 {
449 DeviceType devType = deviceType;
450 int32_t devId = deviceId;
451 DeviceStreamInfo streamInfo = audioStreamInfo;
452
453 // If api target version < 11 && does not set deviceType, fix api compatibility.
454 if (apiVersion < API_11 && (deviceType == DEVICE_TYPE_NONE || deviceType == DEVICE_TYPE_INVALID)) {
455 // DeviceType use speaker or mic instead.
456 if (deviceRole == OUTPUT_DEVICE) {
457 devType = DEVICE_TYPE_SPEAKER;
458 devId = 1; // 1 default speaker device id.
459 } else if (deviceRole == INPUT_DEVICE) {
460 devType = DEVICE_TYPE_MIC;
461 devId = 2; // 2 default mic device id.
462 }
463
464 //If does not set sampleRates use SAMPLE_RATE_44100 instead.
465 if (streamInfo.samplingRate.empty()) {
466 streamInfo.samplingRate.insert(SAMPLE_RATE_44100);
467 }
468 // If does not set channelCounts use STEREO instead.
469 if (streamInfo.channels.empty()) {
470 streamInfo.channels.insert(STEREO);
471 }
472 }
473
474 return parcel.WriteInt32(static_cast<int32_t>(devType))
475 && parcel.WriteInt32(static_cast<int32_t>(deviceRole))
476 && parcel.WriteInt32(devId)
477 && parcel.WriteInt32(channelMasks)
478 && parcel.WriteInt32(channelIndexMasks)
479 && parcel.WriteString((!hasBTPermission && (deviceType == DEVICE_TYPE_BLUETOOTH_A2DP
480 || deviceType == DEVICE_TYPE_BLUETOOTH_SCO)) ? "" : deviceName)
481 && parcel.WriteString((!hasBTPermission && (deviceType == DEVICE_TYPE_BLUETOOTH_A2DP
482 || deviceType == DEVICE_TYPE_BLUETOOTH_SCO)) ? "" : macAddress)
483 && streamInfo.Marshalling(parcel)
484 && parcel.WriteString(hasSystemPermission ? networkId : "")
485 && parcel.WriteString(displayName)
486 && parcel.WriteInt32(hasSystemPermission ? interruptGroupId : INVALID_GROUP_ID)
487 && parcel.WriteInt32(hasSystemPermission ? volumeGroupId : INVALID_GROUP_ID)
488 && parcel.WriteBool(isLowLatencyDevice)
489 && parcel.WriteInt32(a2dpOffloadFlag)
490 && parcel.WriteInt32(static_cast<int32_t>(deviceCategory));
491 }
Unmarshalling(Parcel & parcel)492 void Unmarshalling(Parcel &parcel)
493 {
494 deviceType = static_cast<DeviceType>(parcel.ReadInt32());
495 deviceRole = static_cast<DeviceRole>(parcel.ReadInt32());
496 deviceId = parcel.ReadInt32();
497 channelMasks = parcel.ReadInt32();
498 channelIndexMasks = parcel.ReadInt32();
499 deviceName = parcel.ReadString();
500 macAddress = parcel.ReadString();
501 audioStreamInfo.Unmarshalling(parcel);
502 networkId = parcel.ReadString();
503 displayName = parcel.ReadString();
504 interruptGroupId = parcel.ReadInt32();
505 volumeGroupId = parcel.ReadInt32();
506 isLowLatencyDevice = parcel.ReadBool();
507 a2dpOffloadFlag = parcel.ReadInt32();
508 deviceCategory = static_cast<DeviceCategory>(parcel.ReadInt32());
509 }
510
IsSameDeviceInfo(const DeviceInfo & deviceInfo)511 bool IsSameDeviceInfo(const DeviceInfo &deviceInfo) const
512 {
513 return deviceType == deviceInfo.deviceType &&
514 deviceRole == deviceInfo.deviceRole &&
515 macAddress == deviceInfo.macAddress &&
516 networkId == deviceInfo.networkId;
517 }
518 };
519
520 enum class AudioStreamDeviceChangeReason {
521 UNKNOWN = 0,
522 NEW_DEVICE_AVAILABLE = 1,
523 OLD_DEVICE_UNAVALIABLE = 2,
524 OVERRODE = 3
525 };
526
527 class AudioStreamDeviceChangeReasonExt {
528 public:
529 enum class ExtEnum {
530 UNKNOWN = 0,
531 NEW_DEVICE_AVAILABLE = 1,
532 OLD_DEVICE_UNAVALIABLE = 2,
533 OVERRODE = 3,
534 MIN = 1000,
535 OLD_DEVICE_UNAVALIABLE_EXT = 1000,
536 SET_AUDIO_SCENE = 1001,
537 };
538
AudioStreamDeviceChangeReason()539 operator AudioStreamDeviceChangeReason() const
540 {
541 if (reason_ < ExtEnum::MIN) {
542 return static_cast<AudioStreamDeviceChangeReason>(reason_);
543 } else {
544 return AudioStreamDeviceChangeReason::UNKNOWN;
545 }
546 }
547
548 operator int() const
549 {
550 return static_cast<int>(reason_);
551 }
552
AudioStreamDeviceChangeReasonExt(const AudioStreamDeviceChangeReason & reason)553 AudioStreamDeviceChangeReasonExt(const AudioStreamDeviceChangeReason &reason)
554 : reason_(static_cast<ExtEnum>(reason)) {}
555
AudioStreamDeviceChangeReasonExt(const ExtEnum & reason)556 AudioStreamDeviceChangeReasonExt(const ExtEnum &reason) : reason_(reason) {}
557
IsOldDeviceUnavaliable()558 bool IsOldDeviceUnavaliable() const
559 {
560 return reason_ == ExtEnum::OLD_DEVICE_UNAVALIABLE;
561 }
562
IsOldDeviceUnavaliableExt()563 bool IsOldDeviceUnavaliableExt() const
564 {
565 return reason_ == ExtEnum::OLD_DEVICE_UNAVALIABLE_EXT;
566 }
567
isOverride()568 bool isOverride() const
569 {
570 return reason_ == ExtEnum::OVERRODE;
571 }
572
isSetAudioScene()573 bool isSetAudioScene() const
574 {
575 return reason_ == ExtEnum::SET_AUDIO_SCENE;
576 }
577 private:
578 ExtEnum reason_;
579 };
580 } // namespace AudioStandard
581 } // namespace OHOS
582 #endif // AUDIO_DEVICE_INFO_H