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 #ifndef LOG_TAG
16 #define LOG_TAG "AudioConnectedDevice"
17 #endif
18
19 #include "audio_connected_device.h"
20 #include <ability_manager_client.h>
21 #include "iservice_registry.h"
22 #include "parameter.h"
23 #include "parameters.h"
24 #include "audio_policy_log.h"
25 #include "audio_manager_listener_stub.h"
26 #include "audio_inner_call.h"
27 #include "media_monitor_manager.h"
28 #include "audio_spatialization_service.h"
29
30
31 #include "audio_policy_utils.h"
32
33 namespace OHOS {
34 namespace AudioStandard {
35
IsConnectedOutputDevice(const std::shared_ptr<AudioDeviceDescriptor> & desc)36 bool AudioConnectedDevice::IsConnectedOutputDevice(const std::shared_ptr<AudioDeviceDescriptor> &desc)
37 {
38 DeviceType deviceType = desc->deviceType_;
39
40 CHECK_AND_RETURN_RET_LOG(desc->deviceRole_ == DeviceRole::OUTPUT_DEVICE, false,
41 "Not output device!");
42
43 auto isPresent = [&deviceType] (const std::shared_ptr<AudioDeviceDescriptor> &desc) {
44 CHECK_AND_RETURN_RET_LOG(desc != nullptr, false, "Invalid device descriptor");
45 if (deviceType == DEVICE_TYPE_FILE_SINK) {
46 return false;
47 }
48 return ((deviceType == desc->deviceType_) && (desc->deviceRole_ == DeviceRole::OUTPUT_DEVICE));
49 };
50
51 auto itr = std::find_if(connectedDevices_.begin(), connectedDevices_.end(), isPresent);
52 CHECK_AND_RETURN_RET_LOG(itr != connectedDevices_.end(), false, "Device not available");
53
54 return true;
55 }
56
CheckExistOutputDevice(DeviceType activeDevice,std::string macAddress)57 std::shared_ptr<AudioDeviceDescriptor> AudioConnectedDevice::CheckExistOutputDevice(DeviceType activeDevice,
58 std::string macAddress)
59 {
60 auto isOutputDevicePresent = [&activeDevice, &macAddress] (const std::shared_ptr<AudioDeviceDescriptor> &desc) {
61 CHECK_AND_RETURN_RET_LOG(desc != nullptr, false, "Invalid device descriptor");
62 if ((activeDevice == desc->deviceType_) && (OUTPUT_DEVICE == desc->deviceRole_)) {
63 if (activeDevice == DEVICE_TYPE_BLUETOOTH_A2DP) {
64 // If the device type is A2DP, need to compare mac address in addition.
65 return desc->macAddress_ == macAddress;
66 }
67 return true;
68 }
69 return false;
70 };
71
72 auto itr = std::find_if(connectedDevices_.begin(), connectedDevices_.end(), isOutputDevicePresent);
73 if (itr != connectedDevices_.end()) {
74 return *itr;
75 }
76 return nullptr;
77 }
78
CheckExistInputDevice(DeviceType activeDevice)79 std::shared_ptr<AudioDeviceDescriptor> AudioConnectedDevice::CheckExistInputDevice(DeviceType activeDevice)
80 {
81 auto isInputDevicePresent = [&activeDevice] (const std::shared_ptr<AudioDeviceDescriptor> &desc) {
82 CHECK_AND_RETURN_RET_LOG(desc != nullptr, false, "Invalid device descriptor");
83 return ((activeDevice == desc->deviceType_) && (INPUT_DEVICE == desc->deviceRole_));
84 };
85
86 auto itr = std::find_if(connectedDevices_.begin(), connectedDevices_.end(), isInputDevicePresent);
87 if (itr != connectedDevices_.end()) {
88 return *itr;
89 }
90 return nullptr;
91 }
92
GetConnectedDeviceByType(int32_t deviceType)93 std::shared_ptr<AudioDeviceDescriptor> AudioConnectedDevice::GetConnectedDeviceByType(int32_t deviceType)
94 {
95 auto isPresent = [&deviceType] (const std::shared_ptr<AudioDeviceDescriptor> &desc) {
96 if (deviceType == desc->deviceType_) {
97 return true;
98 }
99 return false;
100 };
101 auto it = std::find_if(connectedDevices_.begin(), connectedDevices_.end(), isPresent);
102 if (it != connectedDevices_.end()) {
103 return *it;
104 }
105 return nullptr;
106 }
107
GetConnectedDeviceByType(std::string networkId,DeviceType deviceType)108 std::shared_ptr<AudioDeviceDescriptor> AudioConnectedDevice::GetConnectedDeviceByType(
109 std::string networkId, DeviceType deviceType)
110 {
111 auto isPresent = [&networkId, &deviceType] (const std::shared_ptr<AudioDeviceDescriptor> &desc) {
112 if (deviceType == desc->deviceType_ && networkId == desc->networkId_) {
113 return true;
114 }
115 return false;
116 };
117 auto it = std::find_if(connectedDevices_.begin(), connectedDevices_.end(), isPresent);
118 if (it != connectedDevices_.end()) {
119 return *it;
120 }
121 return nullptr;
122 }
123
GetConnectedDeviceByType(std::string networkId,DeviceType deviceType,std::string macAddress)124 std::shared_ptr<AudioDeviceDescriptor> AudioConnectedDevice::GetConnectedDeviceByType(
125 std::string networkId, DeviceType deviceType, std::string macAddress)
126 {
127 auto isPresent = [&networkId, &deviceType, &macAddress] (const std::shared_ptr<AudioDeviceDescriptor> &desc) {
128 if (deviceType == desc->deviceType_ && networkId == desc->networkId_ && macAddress == desc->macAddress_) {
129 return true;
130 }
131 return false;
132 };
133 auto it = std::find_if(connectedDevices_.begin(), connectedDevices_.end(), isPresent);
134 if (it != connectedDevices_.end()) {
135 return *it;
136 }
137 return nullptr;
138 }
139
GetAllConnectedDeviceByType(std::string networkId,DeviceType deviceType,std::string macAddress,DeviceRole deviceRole,std::vector<std::shared_ptr<AudioDeviceDescriptor>> & descForCb)140 void AudioConnectedDevice::GetAllConnectedDeviceByType(std::string networkId, DeviceType deviceType,
141 std::string macAddress, DeviceRole deviceRole, std::vector<std::shared_ptr<AudioDeviceDescriptor>> &descForCb)
142 {
143 auto isPresent =
144 [&networkId, &deviceType, &macAddress, &deviceRole] (const std::shared_ptr<AudioDeviceDescriptor> &desc) {
145 if (deviceType == desc->deviceType_ && networkId == desc->networkId_ && macAddress == desc->macAddress_
146 && (!IsUsb(desc->deviceType_) || deviceRole == desc->deviceRole_)) {
147 return true;
148 }
149 return false;
150 };
151 auto it = std::find_if(connectedDevices_.begin(), connectedDevices_.end(), isPresent);
152 while (it != connectedDevices_.end()) {
153 descForCb.push_back(*it);
154 it = std::find_if(std::next(it), connectedDevices_.end(), isPresent);
155 }
156 return;
157 }
158
DelConnectedDevice(std::string networkId,DeviceType deviceType,std::string macAddress,DeviceRole deviceRole)159 void AudioConnectedDevice::DelConnectedDevice(std::string networkId, DeviceType deviceType, std::string macAddress,
160 DeviceRole deviceRole)
161 {
162 auto isPresent = [&deviceType, &networkId, &macAddress,
163 &deviceRole] (const std::shared_ptr<AudioDeviceDescriptor> &descriptor) {
164 return descriptor->deviceType_ == deviceType && descriptor->networkId_ == networkId
165 && descriptor->macAddress_ == macAddress &&
166 (!IsUsb(descriptor->deviceType_) || descriptor->deviceRole_ == deviceRole);
167 };
168
169 connectedDevices_.erase(std::remove_if(connectedDevices_.begin(), connectedDevices_.end(), isPresent),
170 connectedDevices_.end());
171 return;
172 }
173
DelConnectedDevice(std::string networkId,DeviceType deviceType,std::string macAddress)174 void AudioConnectedDevice::DelConnectedDevice(std::string networkId, DeviceType deviceType, std::string macAddress)
175 {
176 auto isPresent =
177 [&deviceType, &networkId, &macAddress] (const std::shared_ptr<AudioDeviceDescriptor> &descriptor) {
178 return descriptor->deviceType_ == deviceType && descriptor->networkId_ == networkId
179 && descriptor->macAddress_ == macAddress;
180 };
181
182 connectedDevices_.erase(std::remove_if(connectedDevices_.begin(), connectedDevices_.end(), isPresent),
183 connectedDevices_.end());
184 return;
185 }
186
DelConnectedDevice(std::string networkId,DeviceType deviceType)187 void AudioConnectedDevice::DelConnectedDevice(std::string networkId, DeviceType deviceType)
188 {
189 auto isPresent = [&deviceType, &networkId] (const std::shared_ptr<AudioDeviceDescriptor> &descriptor) {
190 return descriptor->deviceType_ == deviceType && descriptor->networkId_ == networkId;
191 };
192
193 connectedDevices_.erase(std::remove_if(connectedDevices_.begin(), connectedDevices_.end(), isPresent),
194 connectedDevices_.end());
195 return;
196 }
197
AddConnectedDevice(std::shared_ptr<AudioDeviceDescriptor> remoteDeviceDescriptor)198 void AudioConnectedDevice::AddConnectedDevice(std::shared_ptr<AudioDeviceDescriptor> remoteDeviceDescriptor)
199 {
200 connectedDevices_.insert(connectedDevices_.begin(), remoteDeviceDescriptor);
201 return;
202 }
203
CheckDeviceConnected(std::string selectedDevice)204 bool AudioConnectedDevice::CheckDeviceConnected(std::string selectedDevice)
205 {
206 for (auto device : connectedDevices_) {
207 if (AudioPolicyUtils::GetInstance().GetRemoteModuleName(device->networkId_, device->deviceRole_)
208 == selectedDevice) {
209 return true;
210 }
211 }
212 return false;
213 }
214
SetDisplayName(const std::string & deviceName,bool isLocalDevice)215 void AudioConnectedDevice::SetDisplayName(const std::string &deviceName, bool isLocalDevice)
216 {
217 for (const auto& deviceInfo : connectedDevices_) {
218 if ((isLocalDevice && deviceInfo->networkId_ == LOCAL_NETWORK_ID) ||
219 (!isLocalDevice && deviceInfo->networkId_ != LOCAL_NETWORK_ID)) {
220 deviceInfo->displayName_ = deviceName;
221 }
222 }
223 }
224
SetDmDeviceType(const uint16_t dmDeviceType)225 void AudioConnectedDevice::SetDmDeviceType(const uint16_t dmDeviceType)
226 {
227 for (const auto& deviceInfo : connectedDevices_) {
228 if (deviceInfo->networkId_ != LOCAL_NETWORK_ID) {
229 deviceInfo->dmDeviceType_ = dmDeviceType;
230 }
231 }
232 }
233
SetDisplayName(const std::string macAddress,const std::string deviceName)234 void AudioConnectedDevice::SetDisplayName(const std::string macAddress, const std::string deviceName)
235 {
236 for (auto device : connectedDevices_) {
237 if (device->macAddress_ == macAddress) {
238 device->deviceName_ = deviceName;
239 int32_t bluetoothId_ = device->deviceId_;
240 std::string name_ = device->deviceName_;
241 AUDIO_INFO_LOG("bluetoothId %{public}d alias name changing to %{public}s", bluetoothId_, name_.c_str());
242 }
243 }
244 }
245
UpdateConnectDevice(DeviceType deviceType,const std::string & macAddress,const std::string & deviceName,const AudioStreamInfo & streamInfo)246 void AudioConnectedDevice::UpdateConnectDevice(DeviceType deviceType, const std::string &macAddress,
247 const std::string &deviceName, const AudioStreamInfo &streamInfo)
248 {
249 auto isPresent = [&deviceType, &macAddress] (const std::shared_ptr<AudioDeviceDescriptor> &descriptor) {
250 return descriptor->macAddress_ == macAddress && descriptor->deviceType_ == deviceType;
251 };
252
253 auto it = std::find_if(connectedDevices_.begin(), connectedDevices_.end(), isPresent);
254 if (it != connectedDevices_.end()) {
255 (*it)->deviceName_ = deviceName;
256 (*it)->audioStreamInfo_ = streamInfo;
257 }
258 }
259
GetDevicesInner(DeviceFlag deviceFlag)260 std::vector<std::shared_ptr<AudioDeviceDescriptor>> AudioConnectedDevice::GetDevicesInner(DeviceFlag deviceFlag)
261 {
262 std::vector<std::shared_ptr<AudioDeviceDescriptor>> deviceList = {};
263
264 CHECK_AND_RETURN_RET_LOG(deviceFlag >= DeviceFlag::OUTPUT_DEVICES_FLAG &&
265 deviceFlag <= DeviceFlag::ALL_L_D_DEVICES_FLAG,
266 deviceList, "Invalid flag provided %{public}d", deviceFlag);
267
268 CHECK_AND_RETURN_RET(deviceFlag != DeviceFlag::ALL_L_D_DEVICES_FLAG, connectedDevices_);
269
270 for (auto device : connectedDevices_) {
271 if (device == nullptr) {
272 continue;
273 }
274 bool filterAllLocal = deviceFlag == DeviceFlag::ALL_DEVICES_FLAG && device->networkId_ == LOCAL_NETWORK_ID;
275 bool filterLocalOutput = deviceFlag == DeviceFlag::OUTPUT_DEVICES_FLAG
276 && device->networkId_ == LOCAL_NETWORK_ID
277 && device->deviceRole_ == DeviceRole::OUTPUT_DEVICE;
278 bool filterLocalInput = deviceFlag == DeviceFlag::INPUT_DEVICES_FLAG
279 && device->networkId_ == LOCAL_NETWORK_ID
280 && device->deviceRole_ == DeviceRole::INPUT_DEVICE;
281
282 bool filterAllRemote = deviceFlag == DeviceFlag::ALL_DISTRIBUTED_DEVICES_FLAG
283 && device->networkId_ != LOCAL_NETWORK_ID;
284 bool filterRemoteOutput = deviceFlag == DeviceFlag::DISTRIBUTED_OUTPUT_DEVICES_FLAG
285 && (device->networkId_ != LOCAL_NETWORK_ID || device->deviceType_ == DEVICE_TYPE_REMOTE_CAST)
286 && device->deviceRole_ == DeviceRole::OUTPUT_DEVICE;
287 bool filterRemoteInput = deviceFlag == DeviceFlag::DISTRIBUTED_INPUT_DEVICES_FLAG
288 && device->networkId_ != LOCAL_NETWORK_ID
289 && device->deviceRole_ == DeviceRole::INPUT_DEVICE;
290
291 if (filterAllLocal || filterLocalOutput || filterLocalInput || filterAllRemote || filterRemoteOutput
292 || filterRemoteInput) {
293 std::shared_ptr<AudioDeviceDescriptor> devDesc = std::make_shared<AudioDeviceDescriptor>(*device);
294 deviceList.push_back(devDesc);
295 }
296 }
297
298 AUDIO_DEBUG_LOG("GetDevices list size = [%{public}zu]", deviceList.size());
299 return deviceList;
300 }
301
FindConnectedHeadset()302 DeviceType AudioConnectedDevice::FindConnectedHeadset()
303 {
304 const auto& itr = std::find_if(connectedDevices_.begin(), connectedDevices_.end(),
305 [](const std::shared_ptr<AudioDeviceDescriptor> &devDesc) {
306 CHECK_AND_RETURN_RET_LOG(devDesc != nullptr, false, "Invalid device descriptor");
307 return ((devDesc->deviceType_ == DEVICE_TYPE_WIRED_HEADSET) ||
308 (devDesc->deviceType_ == DEVICE_TYPE_WIRED_HEADPHONES) ||
309 (devDesc->deviceType_ == DEVICE_TYPE_USB_HEADSET) ||
310 (devDesc->deviceType_ == DEVICE_TYPE_DP) ||
311 (devDesc->deviceType_ == DEVICE_TYPE_USB_ARM_HEADSET) ||
312 (devDesc->deviceType_ == DEVICE_TYPE_HDMI));
313 });
314
315 DeviceType retType = DEVICE_TYPE_NONE;
316 if (itr != connectedDevices_.end()) {
317 retType = (*itr)->deviceType_;
318 }
319 return retType;
320 }
321
GetCopy()322 std::vector<std::shared_ptr<AudioDeviceDescriptor>> AudioConnectedDevice::GetCopy()
323 {
324 return connectedDevices_;
325 }
326
GetDevicesForGroup(GroupType type,int32_t groupId)327 std::vector<std::shared_ptr<AudioDeviceDescriptor>> AudioConnectedDevice::GetDevicesForGroup(GroupType type,
328 int32_t groupId)
329 {
330 std::vector<std::shared_ptr<AudioDeviceDescriptor>> devices = {};
331 for (auto devDes : connectedDevices_) {
332 if (devDes == nullptr) {
333 continue;
334 }
335 bool inVolumeGroup = type == VOLUME_TYPE && devDes->volumeGroupId_ == groupId;
336 bool inInterruptGroup = type == INTERRUPT_TYPE && devDes->interruptGroupId_ == groupId;
337
338 if (inVolumeGroup || inInterruptGroup) {
339 std::shared_ptr<AudioDeviceDescriptor> device = std::make_shared<AudioDeviceDescriptor>(*devDes);
340 devices.push_back(device);
341 }
342 }
343 return devices;
344 }
345
IsArmDevice(const std::string & address,const DeviceRole role)346 bool AudioConnectedDevice::IsArmDevice(const std::string& address, const DeviceRole role)
347 {
348 return std::any_of(connectedDevices_.begin(), connectedDevices_.end(),
349 [&address, &role](const auto& item) {
350 return (item->deviceType_ == DEVICE_TYPE_USB_ARM_HEADSET &&
351 item->macAddress_ == address && item->deviceRole_ == role);
352 });
353 }
354
HasArm(const DeviceRole role)355 bool AudioConnectedDevice::HasArm(const DeviceRole role)
356 {
357 return std::find_if(connectedDevices_.cbegin(), connectedDevices_.cend(), [role](const auto& item) {
358 return item->deviceType_ == DEVICE_TYPE_USB_ARM_HEADSET && item->deviceRole_ == role;
359 }) != connectedDevices_.cend();
360 }
361
HasHifi(const DeviceRole role)362 bool AudioConnectedDevice::HasHifi(const DeviceRole role)
363 {
364 return std::find_if(connectedDevices_.cbegin(), connectedDevices_.cend(), [role](const auto& item) {
365 return item->deviceType_ == DEVICE_TYPE_USB_HEADSET && item->deviceRole_ == role;
366 }) != connectedDevices_.cend();
367 }
368
GetUsbDeviceDescriptor(const std::string & address,const DeviceRole role)369 std::shared_ptr<AudioDeviceDescriptor> AudioConnectedDevice::GetUsbDeviceDescriptor(const std::string &address,
370 const DeviceRole role)
371 {
372 auto it = std::find_if(connectedDevices_.cbegin(), connectedDevices_.cend(), [&address, role](const auto &item) {
373 return IsUsb(item->deviceType_) && item->macAddress_ == address && item->deviceRole_ == role;
374 });
375 if (it != connectedDevices_.cend()) {
376 return *it;
377 }
378 return nullptr;
379 }
380
GetSha256EncryptAddress(const std::string & address)381 static std::string GetSha256EncryptAddress(const std::string& address)
382 {
383 const int32_t HexWidth = 2;
384 unsigned char hash[SHA256_DIGEST_LENGTH];
385 SHA256(reinterpret_cast<const unsigned char *>(address.c_str()), address.size(), hash);
386 std::stringstream ss;
387 for (int32_t i = 0; i < SHA256_DIGEST_LENGTH; ++i) {
388 ss << std::hex << std::setw(HexWidth) << std::setfill('0') << (int32_t)hash[i];
389 }
390 return ss.str();
391 }
392
UpdateSpatializationSupported(const std::string macAddress,const bool support)393 void AudioConnectedDevice::UpdateSpatializationSupported(const std::string macAddress, const bool support)
394 {
395 for (auto device : connectedDevices_) {
396 std::string encryAddress = GetSha256EncryptAddress(device->macAddress_);
397 if (encryAddress == macAddress && device->deviceType_ == DEVICE_TYPE_BLUETOOTH_A2DP &&
398 device->spatializationSupported_ != support) {
399 device->spatializationSupported_ = support;
400 AUDIO_INFO_LOG("spatializationSupported is set to %{public}d", support);
401 }
402 }
403 }
404 }
405 }