• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }