1 /*
2 * Copyright (c) 2021-2025 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
16 #include "audio_service_log.h"
17 #include "audio_device_descriptor.h"
18
19 namespace OHOS {
20 namespace AudioStandard {
AudioDeviceDescriptor(int32_t descriptorType)21 AudioDeviceDescriptor::AudioDeviceDescriptor(int32_t descriptorType)
22 : AudioDeviceDescriptor(DeviceType::DEVICE_TYPE_NONE, DeviceRole::DEVICE_ROLE_NONE)
23 {
24 descriptorType_ = descriptorType;
25 if (descriptorType_ == DEVICE_INFO) {
26 deviceType_ = DeviceType(0);
27 deviceRole_ = DeviceRole(0);
28 networkId_ = "";
29 }
30 }
31
AudioDeviceDescriptor(DeviceType type,DeviceRole role)32 AudioDeviceDescriptor::AudioDeviceDescriptor(DeviceType type, DeviceRole role)
33 : deviceType_(type), deviceRole_(role)
34 {
35 deviceId_ = 0;
36 audioStreamInfo_ = {};
37 channelMasks_ = 0;
38 channelIndexMasks_ = 0;
39 deviceName_ = "";
40 macAddress_ = "";
41 volumeGroupId_ = 0;
42 interruptGroupId_ = 0;
43 networkId_ = LOCAL_NETWORK_ID;
44 displayName_ = "";
45 deviceCategory_ = CATEGORY_DEFAULT;
46 connectTimeStamp_ = 0;
47 connectState_ = CONNECTED;
48 pairDeviceDescriptor_ = nullptr;
49 isScoRealConnected_ = false;
50 isEnable_ = true;
51 exceptionFlag_ = false;
52 isLowLatencyDevice_ = false;
53 a2dpOffloadFlag_ = 0;
54 descriptorType_ = AUDIO_DEVICE_DESCRIPTOR;
55 spatializationSupported_ = false;
56 }
57
AudioDeviceDescriptor(DeviceType type,DeviceRole role,int32_t interruptGroupId,int32_t volumeGroupId,std::string networkId)58 AudioDeviceDescriptor::AudioDeviceDescriptor(DeviceType type, DeviceRole role, int32_t interruptGroupId,
59 int32_t volumeGroupId, std::string networkId)
60 : deviceType_(type), deviceRole_(role), interruptGroupId_(interruptGroupId), volumeGroupId_(volumeGroupId),
61 networkId_(networkId)
62 {
63 deviceId_ = 0;
64 audioStreamInfo_ = {};
65 channelMasks_ = 0;
66 channelIndexMasks_ = 0;
67 deviceName_ = "";
68 macAddress_ = "";
69 displayName_ = "";
70 deviceCategory_ = CATEGORY_DEFAULT;
71 connectTimeStamp_ = 0;
72 connectState_ = CONNECTED;
73 pairDeviceDescriptor_ = nullptr;
74 isScoRealConnected_ = false;
75 isEnable_ = true;
76 exceptionFlag_ = false;
77 isLowLatencyDevice_ = false;
78 a2dpOffloadFlag_ = 0;
79 descriptorType_ = AUDIO_DEVICE_DESCRIPTOR;
80 spatializationSupported_ = false;
81 }
82
AudioDeviceDescriptor(const AudioDeviceDescriptor & deviceDescriptor)83 AudioDeviceDescriptor::AudioDeviceDescriptor(const AudioDeviceDescriptor &deviceDescriptor)
84 {
85 deviceId_ = deviceDescriptor.deviceId_;
86 deviceName_ = deviceDescriptor.deviceName_;
87 macAddress_ = deviceDescriptor.macAddress_;
88 deviceType_ = deviceDescriptor.deviceType_;
89 deviceRole_ = deviceDescriptor.deviceRole_;
90 audioStreamInfo_.channels = deviceDescriptor.audioStreamInfo_.channels;
91 audioStreamInfo_.encoding = deviceDescriptor.audioStreamInfo_.encoding;
92 audioStreamInfo_.format = deviceDescriptor.audioStreamInfo_.format;
93 audioStreamInfo_.samplingRate = deviceDescriptor.audioStreamInfo_.samplingRate;
94 channelMasks_ = deviceDescriptor.channelMasks_;
95 channelIndexMasks_ = deviceDescriptor.channelIndexMasks_;
96 volumeGroupId_ = deviceDescriptor.volumeGroupId_;
97 interruptGroupId_ = deviceDescriptor.interruptGroupId_;
98 networkId_ = deviceDescriptor.networkId_;
99 dmDeviceType_ = deviceDescriptor.dmDeviceType_;
100 displayName_ = deviceDescriptor.displayName_;
101 deviceCategory_ = deviceDescriptor.deviceCategory_;
102 connectTimeStamp_ = deviceDescriptor.connectTimeStamp_;
103 connectState_ = deviceDescriptor.connectState_;
104 pairDeviceDescriptor_ = deviceDescriptor.pairDeviceDescriptor_;
105 isScoRealConnected_ = deviceDescriptor.isScoRealConnected_;
106 isEnable_ = deviceDescriptor.isEnable_;
107 exceptionFlag_ = deviceDescriptor.exceptionFlag_;
108 // DeviceInfo
109 isLowLatencyDevice_ = deviceDescriptor.isLowLatencyDevice_;
110 a2dpOffloadFlag_ = deviceDescriptor.a2dpOffloadFlag_;
111 // Other
112 descriptorType_ = deviceDescriptor.descriptorType_;
113 hasPair_ = deviceDescriptor.hasPair_;
114 spatializationSupported_ = deviceDescriptor.spatializationSupported_;
115 }
116
AudioDeviceDescriptor(const std::shared_ptr<AudioDeviceDescriptor> & deviceDescriptor)117 AudioDeviceDescriptor::AudioDeviceDescriptor(const std::shared_ptr<AudioDeviceDescriptor> &deviceDescriptor)
118 {
119 CHECK_AND_RETURN_LOG(deviceDescriptor != nullptr, "Error input parameter");
120 deviceId_ = deviceDescriptor->deviceId_;
121 deviceName_ = deviceDescriptor->deviceName_;
122 macAddress_ = deviceDescriptor->macAddress_;
123 deviceType_ = deviceDescriptor->deviceType_;
124 deviceRole_ = deviceDescriptor->deviceRole_;
125 audioStreamInfo_.channels = deviceDescriptor->audioStreamInfo_.channels;
126 audioStreamInfo_.encoding = deviceDescriptor->audioStreamInfo_.encoding;
127 audioStreamInfo_.format = deviceDescriptor->audioStreamInfo_.format;
128 audioStreamInfo_.samplingRate = deviceDescriptor->audioStreamInfo_.samplingRate;
129 channelMasks_ = deviceDescriptor->channelMasks_;
130 channelIndexMasks_ = deviceDescriptor->channelIndexMasks_;
131 volumeGroupId_ = deviceDescriptor->volumeGroupId_;
132 interruptGroupId_ = deviceDescriptor->interruptGroupId_;
133 networkId_ = deviceDescriptor->networkId_;
134 dmDeviceType_ = deviceDescriptor->dmDeviceType_;
135 displayName_ = deviceDescriptor->displayName_;
136 deviceCategory_ = deviceDescriptor->deviceCategory_;
137 connectTimeStamp_ = deviceDescriptor->connectTimeStamp_;
138 connectState_ = deviceDescriptor->connectState_;
139 pairDeviceDescriptor_ = deviceDescriptor->pairDeviceDescriptor_;
140 isScoRealConnected_ = deviceDescriptor->isScoRealConnected_;
141 isEnable_ = deviceDescriptor->isEnable_;
142 exceptionFlag_ = deviceDescriptor->exceptionFlag_;
143 // DeviceInfo
144 isLowLatencyDevice_ = deviceDescriptor->isLowLatencyDevice_;
145 a2dpOffloadFlag_ = deviceDescriptor->a2dpOffloadFlag_;
146 // Other
147 descriptorType_ = deviceDescriptor->descriptorType_;
148 hasPair_ = deviceDescriptor->hasPair_;
149 spatializationSupported_ = deviceDescriptor->spatializationSupported_;
150 }
151
~AudioDeviceDescriptor()152 AudioDeviceDescriptor::~AudioDeviceDescriptor()
153 {
154 pairDeviceDescriptor_ = nullptr;
155 }
156
getType() const157 DeviceType AudioDeviceDescriptor::getType() const
158 {
159 return deviceType_;
160 }
161
getRole() const162 DeviceRole AudioDeviceDescriptor::getRole() const
163 {
164 return deviceRole_;
165 }
166
GetDeviceCategory() const167 DeviceCategory AudioDeviceDescriptor::GetDeviceCategory() const
168 {
169 return deviceCategory_;
170 }
171
IsAudioDeviceDescriptor() const172 bool AudioDeviceDescriptor::IsAudioDeviceDescriptor() const
173 {
174 return descriptorType_ == AUDIO_DEVICE_DESCRIPTOR;
175 }
176
Marshalling(Parcel & parcel) const177 bool AudioDeviceDescriptor::Marshalling(Parcel &parcel) const
178 {
179 if (IsAudioDeviceDescriptor()) {
180 return MarshallingToDeviceDescriptor(parcel);
181 }
182
183 return MarshallingToDeviceInfo(parcel);
184 }
185
MarshallingToDeviceDescriptor(Parcel & parcel) const186 bool AudioDeviceDescriptor::MarshallingToDeviceDescriptor(Parcel &parcel) const
187 {
188 parcel.WriteInt32(MapInternalToExternalDeviceType());
189 parcel.WriteInt32(deviceRole_);
190 parcel.WriteInt32(deviceId_);
191 audioStreamInfo_.Marshalling(parcel);
192 parcel.WriteInt32(channelMasks_);
193 parcel.WriteInt32(channelIndexMasks_);
194 parcel.WriteString(deviceName_);
195 parcel.WriteString(macAddress_);
196 parcel.WriteInt32(interruptGroupId_);
197 parcel.WriteInt32(volumeGroupId_);
198 parcel.WriteString(networkId_);
199 parcel.WriteUint16(dmDeviceType_);
200 parcel.WriteString(displayName_);
201 parcel.WriteInt32(deviceCategory_);
202 parcel.WriteInt32(connectState_);
203 parcel.WriteBool(spatializationSupported_);
204 return true;
205 }
206
MarshallingToDeviceInfo(Parcel & parcel) const207 bool AudioDeviceDescriptor::MarshallingToDeviceInfo(Parcel &parcel) const
208 {
209 return parcel.WriteInt32(static_cast<int32_t>(deviceType_)) &&
210 parcel.WriteInt32(static_cast<int32_t>(deviceRole_)) &&
211 parcel.WriteInt32(deviceId_) &&
212 parcel.WriteInt32(channelMasks_) &&
213 parcel.WriteInt32(channelIndexMasks_) &&
214 parcel.WriteString(deviceName_) &&
215 parcel.WriteString(macAddress_) &&
216 audioStreamInfo_.Marshalling(parcel) &&
217 parcel.WriteString(networkId_) &&
218 parcel.WriteUint16(dmDeviceType_) &&
219 parcel.WriteString(displayName_) &&
220 parcel.WriteInt32(interruptGroupId_) &&
221 parcel.WriteInt32(volumeGroupId_) &&
222 parcel.WriteBool(isLowLatencyDevice_) &&
223 parcel.WriteInt32(a2dpOffloadFlag_) &&
224 parcel.WriteInt32(static_cast<int32_t>(deviceCategory_)) &&
225 parcel.WriteBool(spatializationSupported_);
226 }
227
Marshalling(Parcel & parcel,bool hasBTPermission,bool hasSystemPermission,int32_t apiVersion) const228 bool AudioDeviceDescriptor::Marshalling(Parcel &parcel, bool hasBTPermission, bool hasSystemPermission,
229 int32_t apiVersion) const
230 {
231 return MarshallingToDeviceInfo(parcel, hasBTPermission, hasSystemPermission, apiVersion);
232 }
233
MarshallingToDeviceInfo(Parcel & parcel,bool hasBTPermission,bool hasSystemPermission,int32_t apiVersion) const234 bool AudioDeviceDescriptor::MarshallingToDeviceInfo(Parcel &parcel, bool hasBTPermission, bool hasSystemPermission,
235 int32_t apiVersion) const
236 {
237 DeviceType devType = deviceType_;
238 int32_t devId = deviceId_;
239 DeviceStreamInfo streamInfo = audioStreamInfo_;
240
241 // If api target version < 11 && does not set deviceType, fix api compatibility.
242 if (apiVersion < API_11 && (deviceType_ == DEVICE_TYPE_NONE || deviceType_ == DEVICE_TYPE_INVALID)) {
243 // DeviceType use speaker or mic instead.
244 if (deviceRole_ == OUTPUT_DEVICE) {
245 devType = DEVICE_TYPE_SPEAKER;
246 devId = 1; // 1 default speaker device id.
247 } else if (deviceRole_ == INPUT_DEVICE) {
248 devType = DEVICE_TYPE_MIC;
249 devId = 2; // 2 default mic device id.
250 }
251
252 //If does not set sampleRates use SAMPLE_RATE_44100 instead.
253 if (streamInfo.samplingRate.empty()) {
254 streamInfo.samplingRate.insert(SAMPLE_RATE_44100);
255 }
256 // If does not set channelCounts use STEREO instead.
257 if (streamInfo.channels.empty()) {
258 streamInfo.channels.insert(STEREO);
259 }
260 }
261
262 return parcel.WriteInt32(static_cast<int32_t>(devType)) &&
263 parcel.WriteInt32(static_cast<int32_t>(deviceRole_)) &&
264 parcel.WriteInt32(devId) &&
265 parcel.WriteInt32(channelMasks_) &&
266 parcel.WriteInt32(channelIndexMasks_) &&
267 parcel.WriteString((!hasBTPermission && (deviceType_ == DEVICE_TYPE_BLUETOOTH_A2DP ||
268 deviceType_ == DEVICE_TYPE_BLUETOOTH_SCO)) ? "" : deviceName_) &&
269 parcel.WriteString((!hasBTPermission && (deviceType_ == DEVICE_TYPE_BLUETOOTH_A2DP ||
270 deviceType_ == DEVICE_TYPE_BLUETOOTH_SCO)) ? "" : macAddress_) &&
271 streamInfo.Marshalling(parcel) &&
272 parcel.WriteString(hasSystemPermission ? networkId_ : "") &&
273 parcel.WriteUint16(dmDeviceType_) &&
274 parcel.WriteString(displayName_) &&
275 parcel.WriteInt32(hasSystemPermission ? interruptGroupId_ : INVALID_GROUP_ID) &&
276 parcel.WriteInt32(hasSystemPermission ? volumeGroupId_ : INVALID_GROUP_ID) &&
277 parcel.WriteBool(isLowLatencyDevice_) &&
278 parcel.WriteInt32(a2dpOffloadFlag_) &&
279 parcel.WriteInt32(static_cast<int32_t>(deviceCategory_)) &&
280 parcel.WriteBool(spatializationSupported_);
281 }
282
Unmarshalling(Parcel & parcel)283 void AudioDeviceDescriptor::Unmarshalling(Parcel &parcel)
284 {
285 return UnmarshallingToDeviceInfo(parcel);
286 }
287
UnmarshallingPtr(Parcel & parcel)288 std::shared_ptr<AudioDeviceDescriptor> AudioDeviceDescriptor::UnmarshallingPtr(Parcel &parcel)
289 {
290 std::shared_ptr<AudioDeviceDescriptor> audioDeviceDescriptor = std::make_shared<AudioDeviceDescriptor>();
291 if (audioDeviceDescriptor == nullptr) {
292 return nullptr;
293 }
294
295 audioDeviceDescriptor->UnmarshallingToDeviceDescriptor(parcel);
296 return audioDeviceDescriptor;
297 }
298
UnmarshallingToDeviceDescriptor(Parcel & parcel)299 void AudioDeviceDescriptor::UnmarshallingToDeviceDescriptor(Parcel &parcel)
300 {
301 deviceType_ = static_cast<DeviceType>(parcel.ReadInt32());
302 deviceRole_ = static_cast<DeviceRole>(parcel.ReadInt32());
303 deviceId_ = parcel.ReadInt32();
304 audioStreamInfo_.Unmarshalling(parcel);
305 channelMasks_ = parcel.ReadInt32();
306 channelIndexMasks_ = parcel.ReadInt32();
307 deviceName_ = parcel.ReadString();
308 macAddress_ = parcel.ReadString();
309 interruptGroupId_ = parcel.ReadInt32();
310 volumeGroupId_ = parcel.ReadInt32();
311 networkId_ = parcel.ReadString();
312 dmDeviceType_ = parcel.ReadUint16();
313 displayName_ = parcel.ReadString();
314 deviceCategory_ = static_cast<DeviceCategory>(parcel.ReadInt32());
315 connectState_ = static_cast<ConnectState>(parcel.ReadInt32());
316 spatializationSupported_ = parcel.ReadBool();
317 }
318
UnmarshallingToDeviceInfo(Parcel & parcel)319 void AudioDeviceDescriptor::UnmarshallingToDeviceInfo(Parcel &parcel)
320 {
321 deviceType_ = static_cast<DeviceType>(parcel.ReadInt32());
322 deviceRole_ = static_cast<DeviceRole>(parcel.ReadInt32());
323 deviceId_ = parcel.ReadInt32();
324 channelMasks_ = parcel.ReadInt32();
325 channelIndexMasks_ = parcel.ReadInt32();
326 deviceName_ = parcel.ReadString();
327 macAddress_ = parcel.ReadString();
328 audioStreamInfo_.Unmarshalling(parcel);
329 networkId_ = parcel.ReadString();
330 dmDeviceType_ = parcel.ReadUint16();
331 displayName_ = parcel.ReadString();
332 interruptGroupId_ = parcel.ReadInt32();
333 volumeGroupId_ = parcel.ReadInt32();
334 isLowLatencyDevice_ = parcel.ReadBool();
335 a2dpOffloadFlag_ = parcel.ReadInt32();
336 deviceCategory_ = static_cast<DeviceCategory>(parcel.ReadInt32());
337 spatializationSupported_ = parcel.ReadBool();
338 }
339
SetDeviceInfo(std::string deviceName,std::string macAddress)340 void AudioDeviceDescriptor::SetDeviceInfo(std::string deviceName, std::string macAddress)
341 {
342 deviceName_ = deviceName;
343 macAddress_ = macAddress;
344 }
345
SetDeviceCapability(const DeviceStreamInfo & audioStreamInfo,int32_t channelMask,int32_t channelIndexMasks)346 void AudioDeviceDescriptor::SetDeviceCapability(const DeviceStreamInfo &audioStreamInfo, int32_t channelMask,
347 int32_t channelIndexMasks)
348 {
349 audioStreamInfo_.channels = audioStreamInfo.channels;
350 audioStreamInfo_.encoding = audioStreamInfo.encoding;
351 audioStreamInfo_.format = audioStreamInfo.format;
352 audioStreamInfo_.samplingRate = audioStreamInfo.samplingRate;
353 channelMasks_ = channelMask;
354 channelIndexMasks_ = channelIndexMasks;
355 }
356
IsSameDeviceDesc(const AudioDeviceDescriptor & deviceDescriptor) const357 bool AudioDeviceDescriptor::IsSameDeviceDesc(const AudioDeviceDescriptor &deviceDescriptor) const
358 {
359 return deviceDescriptor.deviceType_ == deviceType_ &&
360 deviceDescriptor.macAddress_ == macAddress_ &&
361 deviceDescriptor.networkId_ == networkId_ &&
362 (!IsUsb(deviceType_) || deviceDescriptor.deviceRole_ == deviceRole_);
363 }
364
IsSameDeviceInfo(const AudioDeviceDescriptor & deviceInfo) const365 bool AudioDeviceDescriptor::IsSameDeviceInfo(const AudioDeviceDescriptor &deviceInfo) const
366 {
367 return deviceType_ == deviceInfo.deviceType_ &&
368 deviceRole_ == deviceInfo.deviceRole_ &&
369 macAddress_ == deviceInfo.macAddress_ &&
370 networkId_ == deviceInfo.networkId_;
371 }
372
IsPairedDeviceDesc(const AudioDeviceDescriptor & deviceDescriptor) const373 bool AudioDeviceDescriptor::IsPairedDeviceDesc(const AudioDeviceDescriptor &deviceDescriptor) const
374 {
375 return ((deviceDescriptor.deviceRole_ == INPUT_DEVICE && deviceRole_ == OUTPUT_DEVICE) ||
376 (deviceDescriptor.deviceRole_ == OUTPUT_DEVICE && deviceRole_ == INPUT_DEVICE)) &&
377 deviceDescriptor.deviceType_ == deviceType_ &&
378 deviceDescriptor.macAddress_ == macAddress_ &&
379 deviceDescriptor.networkId_ == networkId_;
380 }
381
MapInternalToExternalDeviceType() const382 DeviceType AudioDeviceDescriptor::MapInternalToExternalDeviceType() const
383 {
384 switch (deviceType_) {
385 case DEVICE_TYPE_USB_HEADSET:
386 case DEVICE_TYPE_USB_ARM_HEADSET:
387 if (!hasPair_) {
388 #ifdef DETECT_SOUNDBOX
389 return DEVICE_TYPE_USB_DEVICE;
390 #else
391 if (deviceRole_ == INPUT_DEVICE) {
392 return DEVICE_TYPE_USB_DEVICE;
393 }
394 #endif
395 }
396 return DEVICE_TYPE_USB_HEADSET;
397 case DEVICE_TYPE_BLUETOOTH_A2DP_IN:
398 return DEVICE_TYPE_BLUETOOTH_A2DP;
399 default:
400 return deviceType_;
401 }
402 }
403 } // AudioStandard
404 } // namespace OHOS
405