1 /*
2 * Copyright (c) 2024 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 "daudio_sink_manager.h"
17
18 #include <dlfcn.h>
19 #include "if_system_ability_manager.h"
20 #include "iservice_registry.h"
21
22 #include "daudio_constants.h"
23 #include "daudio_errorcode.h"
24 #include "daudio_log.h"
25 #include "daudio_util.h"
26
27 #undef DH_LOG_TAG
28 #define DH_LOG_TAG "DAudioSinkManager"
29
30 namespace OHOS {
31 namespace DistributedHardware {
32 namespace {
33 const std::string PARAM_CLOSE_SPEAKER = "{\"audioParam\":null,\"dhId\":\"" +
34 std::to_string(PIN_OUT_SPEAKER) + "\",\"eventType\":12}";
35 const std::string PARAM_CLOSE_MIC = "{\"audioParam\":null,\"dhId\":\"" +
36 std::to_string(PIN_IN_MIC) + "\",\"eventType\":22}";
37 const int DEFAULT_DEVICE_SECURITY_LEVEL = -1;
38 constexpr uint32_t DAUDIO_SOURCE_SERVICE_MAX_SIZE = 64;
39 }
40
41
42 IMPLEMENT_SINGLE_INSTANCE(DAudioSinkManager);
43 using AVTransProviderClass = IAVEngineProvider *(*)(const std::string &);
44
45 const std::string SENDER_SO_NAME = "libdistributed_av_sender.z.so";
46 const std::string GET_SENDER_PROVIDER_FUNC = "GetAVAudioSenderEngineProvider";
47 const std::string RECEIVER_SO_NAME = "libdistributed_av_receiver.z.so";
48 const std::string GET_RECEIVER_PROVIDER_FUNC = "GetAVAudioReceiverEngineProvider";
DAudioSinkManager()49 DAudioSinkManager::DAudioSinkManager()
50 {
51 DHLOGD("Distributed audio sink manager constructed.");
52 }
53
~DAudioSinkManager()54 DAudioSinkManager::~DAudioSinkManager()
55 {
56 if (devClearThread_.joinable()) {
57 devClearThread_.join();
58 }
59 DHLOGD("Distributed audio sink manager deconstructed.");
60 }
61
Init(const sptr<IDAudioSinkIpcCallback> & sinkCallback)62 int32_t DAudioSinkManager::Init(const sptr<IDAudioSinkIpcCallback> &sinkCallback)
63 {
64 DHLOGI("Init audio sink manager.");
65 {
66 std::lock_guard<std::mutex> lock(ipcCallbackMutex_);
67 initCallback_ = std::make_shared<DeviceInitCallback>();
68 ipcSinkCallback_ = sinkCallback;
69 }
70 CHECK_AND_RETURN_RET_LOG(GetLocalDeviceNetworkId(localNetworkId_) != DH_SUCCESS,
71 ERR_DH_AUDIO_FAILED, "%{public}s", "Get local network id failed.");
72 CHECK_AND_RETURN_RET_LOG(LoadAVReceiverEngineProvider() != DH_SUCCESS,
73 ERR_DH_AUDIO_FAILED, "%{public}s", "Load av receiver engine failed.");
74 CHECK_NULL_RETURN(rcvProviderPtr_, ERR_DH_AUDIO_FAILED);
75 providerListener_ = std::make_shared<EngineProviderListener>();
76 if (rcvProviderPtr_->RegisterProviderCallback(providerListener_) != DH_SUCCESS) {
77 DHLOGE("Register av receiver engine callback failed.");
78 return ERR_DH_AUDIO_FAILED;
79 }
80 DHLOGI("Load av receiver engine success.");
81
82 if (LoadAVSenderEngineProvider() != DH_SUCCESS) {
83 DHLOGE("Load av sender engine provider failed.");
84 return ERR_DH_AUDIO_FAILED;
85 }
86 CHECK_NULL_RETURN(sendProviderPtr_, ERR_DH_AUDIO_FAILED);
87 if (sendProviderPtr_->RegisterProviderCallback(providerListener_) != DH_SUCCESS) {
88 DHLOGE("Register av sender engine callback failed.");
89 return ERR_DH_AUDIO_FAILED;
90 }
91 CHECK_AND_RETURN_RET_LOG(sendProviderPtr_->RegisterProviderCallback(providerListener_) != DH_SUCCESS,
92 ERR_DH_AUDIO_FAILED, "%{public}s", "Register av sender engine callback failed.");
93 DHLOGI("Load av sender engine success.");
94 ctrlListenerCallback_ = std::make_shared<CtrlChannelListener>();
95 ctrlListener_ = std::make_shared<DaudioCtrlChannelListener>(ctrlListenerCallback_);
96 CHECK_AND_RETURN_RET_LOG(ctrlListener_->Init() != DH_SUCCESS, ERR_DH_AUDIO_FAILED, "ctrlListener init failed");
97 DHLOGI("Load ctrl trans success.");
98 return DH_SUCCESS;
99 }
100
UnInit()101 int32_t DAudioSinkManager::UnInit()
102 {
103 DHLOGI("UnInit audio sink manager.");
104 UnloadAVSenderEngineProvider();
105 UnloadAVReceiverEngineProvider();
106 if (ctrlListener_ != nullptr) {
107 ctrlListener_->UnInit();
108 ctrlListener_ = nullptr;
109 ctrlListenerCallback_ = nullptr;
110 }
111 {
112 std::lock_guard<std::mutex> remoteSvrLock(remoteSvrMutex_);
113 sourceServiceMap_.clear();
114 }
115 {
116 std::lock_guard<std::mutex> devMapLock(devMapMutex_);
117 for (auto iter = audioDevMap_.begin(); iter != audioDevMap_.end(); iter++) {
118 if (iter->second != nullptr) {
119 iter->second->SleepAudioDev();
120 }
121 }
122 audioDevMap_.clear();
123 }
124 if (devClearThread_.joinable()) {
125 devClearThread_.join();
126 }
127 ipcSinkCallback_ = nullptr;
128 return DH_SUCCESS;
129 }
130
OnSinkDevReleased(const std::string & devId)131 void DAudioSinkManager::OnSinkDevReleased(const std::string &devId)
132 {
133 DHLOGI("Release audio device devId: %{public}s.", GetAnonyString(devId).c_str());
134 if (devClearThread_.joinable()) {
135 devClearThread_.join();
136 }
137 devClearThread_ = std::thread([this, devId]() { this->ClearAudioDev(devId); });
138 if (pthread_setname_np(devClearThread_.native_handle(), DEVCLEAR_THREAD) != DH_SUCCESS) {
139 DHLOGE("Dev clear thread setname failed.");
140 }
141 }
142
HandleDAudioNotify(const std::string & devId,const std::string & dhId,const int32_t eventType,const std::string & eventContent)143 int32_t DAudioSinkManager::HandleDAudioNotify(const std::string &devId, const std::string &dhId,
144 const int32_t eventType, const std::string &eventContent)
145 {
146 DHLOGD("Receive audio event from devId: %{public}s, event type: %{public}d. event content: %{public}s.",
147 GetAnonyString(devId).c_str(), eventType, eventContent.c_str());
148
149 if (eventContent.length() > DAUDIO_MAX_JSON_LEN || eventContent.empty()
150 || !CheckDevIdIsLegal(devId) || eventType < 0 || eventType > MAX_EVENT_TYPE_NUM) {
151 return ERR_DH_AUDIO_FAILED;
152 }
153
154 // now ctrl channel is also goto here, please sure here not crash.
155 cJSON *jParam = cJSON_Parse(eventContent.c_str());
156 if (CJsonParamCheck(jParam, { KEY_RANDOM_TASK_CODE })) {
157 DHLOGD("Receive audio notify from source, random task code: %{public}s",
158 cJSON_GetObjectItemCaseSensitive(jParam, KEY_RANDOM_TASK_CODE)->valuestring);
159 }
160 bool isDevExisted = false;
161 {
162 std::lock_guard<std::mutex> lock(devMapMutex_);
163 isDevExisted = audioDevMap_.find(devId) != audioDevMap_.end();
164 }
165 if (!isDevExisted) {
166 DHLOGE("Device is not exist, devId: %{public}s, dhId: %{public}s.", GetAnonyString(devId).c_str(),
167 GetAnonyString(dhId).c_str());
168 cJSON_Delete(jParam);
169 return ERR_DH_AUDIO_FAILED;
170 }
171 NotifyEvent(devId, eventType, eventContent);
172 cJSON_Delete(jParam);
173 return DH_SUCCESS;
174 }
175
CreateAudioDevice(const std::string & devId)176 int32_t DAudioSinkManager::CreateAudioDevice(const std::string &devId)
177 {
178 DHLOGI("Create audio sink dev.");
179 std::shared_ptr<DAudioSinkDev> dev = nullptr;
180 {
181 std::lock_guard<std::mutex> lock(devMapMutex_);
182 if (audioDevMap_.find(devId) != audioDevMap_.end()) {
183 DHLOGD("Audio sink dev in map. devId: %{public}s.", GetAnonyString(devId).c_str());
184 dev = audioDevMap_[devId];
185 } else {
186 dev = std::make_shared<DAudioSinkDev>(devId, ipcSinkCallback_);
187 audioDevMap_.emplace(devId, dev);
188 }
189 }
190 int32_t dhId;
191 bool isSpkOrMic = false;
192 if (channelState_ == ChannelState::MIC_CONTROL_OPENED) {
193 dhId = PIN_IN_MIC;
194 isSpkOrMic = false;
195 } else if (channelState_ == ChannelState::SPK_CONTROL_OPENED) {
196 dhId = PIN_OUT_SPEAKER;
197 isSpkOrMic = true;
198 } else {
199 DHLOGE("Channel state error.");
200 return ERR_DH_AUDIO_NOT_SUPPORT;
201 }
202 int32_t ret = InitAudioDevice(dev, devId, isSpkOrMic);
203 cJSON *jParam = cJSON_CreateObject();
204 CHECK_NULL_RETURN(jParam, ERR_DH_AUDIO_NULLPTR);
205 cJSON_AddStringToObject(jParam, KEY_DH_ID, std::to_string(dhId).c_str());
206 cJSON_AddNumberToObject(jParam, KEY_RESULT, ret);
207 char *jsonData = cJSON_PrintUnformatted(jParam);
208 if (jsonData == nullptr) {
209 DHLOGE("Failed to create JSON data.");
210 cJSON_Delete(jParam);
211 return ERR_DH_AUDIO_NULLPTR;
212 }
213 std::string eventContent = std::string(jsonData);
214 cJSON_free(jsonData);
215 cJSON_Delete(jParam);
216 int32_t SLEEP_TIME = 300;
217 std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME));
218 NotifyEvent(devId, CTRL_OPENED, eventContent);
219 return DH_SUCCESS;
220 }
221
InitAudioDevice(std::shared_ptr<DAudioSinkDev> dev,const std::string & devId,bool isSpkOrMic)222 int32_t DAudioSinkManager::InitAudioDevice(std::shared_ptr<DAudioSinkDev> dev, const std::string &devId,
223 bool isSpkOrMic)
224 {
225 DHLOGI("Init audio device.");
226 if (dev == nullptr) {
227 DHLOGE("dev is nullptr.");
228 return ERR_DH_AUDIO_NULLPTR;
229 }
230 int32_t ret;
231 if (isSpkOrMic) {
232 ret = dev->InitAVTransEngines(ChannelState::SPK_CONTROL_OPENED, rcvProviderPtr_);
233 } else {
234 ret = VerifySecurityLevel(devId);
235 if (ret != DH_SUCCESS) {
236 DHLOGE("Verify security level failed.");
237 return ERR_DH_AUDIO_FAILED;
238 }
239 dev->SetDevLevelStatus(true);
240 ret = dev->InitAVTransEngines(ChannelState::MIC_CONTROL_OPENED, sendProviderPtr_);
241 }
242 if (ret != DH_SUCCESS) {
243 DHLOGE("Init av transport engine failed.");
244 dev->JudgeDeviceStatus();
245 return ERR_DH_AUDIO_FAILED;
246 }
247 ret = dev->AwakeAudioDev();
248 if (ret != DH_SUCCESS) {
249 DHLOGE("Awake audio dev failed.");
250 return ERR_DH_AUDIO_FAILED;
251 }
252 return ret;
253 }
254
DAudioNotify(const std::string & devId,const std::string & dhId,const int32_t eventType,const std::string & eventContent)255 int32_t DAudioSinkManager::DAudioNotify(const std::string &devId, const std::string &dhId, const int32_t eventType,
256 const std::string &eventContent)
257 {
258 DHLOGD("Distributed audio notify, devId: %{public}s, dhId: %{public}s, eventType: %{public}d.",
259 GetAnonyString(devId).c_str(), dhId.c_str(), eventType);
260
261 {
262 std::lock_guard<std::mutex> lck(remoteSvrMutex_);
263 auto sinkProxy = sourceServiceMap_.find(devId);
264 if (sinkProxy != sourceServiceMap_.end()) {
265 if (sinkProxy->second != nullptr) {
266 sinkProxy->second->DAudioNotify(localNetworkId_, dhId, eventType, eventContent);
267 return DH_SUCCESS;
268 }
269 }
270 }
271
272 auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
273 CHECK_NULL_RETURN(samgr, ERR_DH_AUDIO_NULLPTR);
274
275 auto remoteObject = samgr->GetSystemAbility(DISTRIBUTED_HARDWARE_AUDIO_SOURCE_SA_ID, devId);
276 CHECK_NULL_RETURN(remoteObject, ERR_DH_AUDIO_NULLPTR);
277
278 sptr<IDAudioSource> remoteSvrProxy = iface_cast<IDAudioSource>(remoteObject);
279 CHECK_NULL_RETURN(remoteSvrProxy, ERR_DH_AUDIO_NULLPTR);
280 {
281 std::lock_guard<std::mutex> lck(remoteSvrMutex_);
282 if (sourceServiceMap_.size() >= DAUDIO_SOURCE_SERVICE_MAX_SIZE) {
283 DHLOGE("Source service map is full, not allow to insert anymore.");
284 return ERR_DH_AUDIO_FAILED;
285 }
286 sourceServiceMap_[devId] = remoteSvrProxy;
287 remoteSvrProxy->DAudioNotify(localNetworkId_, dhId, eventType, eventContent);
288 }
289 return DH_SUCCESS;
290 }
291
NotifyEvent(const std::string & devId,const int32_t eventType,const std::string & eventContent)292 void DAudioSinkManager::NotifyEvent(const std::string &devId, const int32_t eventType, const std::string &eventContent)
293 {
294 AudioEvent audioEvent(eventType, eventContent);
295 std::lock_guard<std::mutex> lock(devMapMutex_);
296 DHLOGD("Notify event, devId: %{public}s.", GetAnonyString(devId).c_str());
297 CHECK_AND_RETURN_LOG(audioDevMap_.find(devId) == audioDevMap_.end(),
298 "%{public}s", "Notify event error, dev not exist.");
299 CHECK_NULL_VOID(audioDevMap_[devId]);
300 audioDevMap_[devId]->NotifyEvent(audioEvent);
301 }
302
ClearAudioDev(const std::string & devId)303 void DAudioSinkManager::ClearAudioDev(const std::string &devId)
304 {
305 std::lock_guard<std::mutex> lock(devMapMutex_);
306 auto dev = audioDevMap_.find(devId);
307 if (dev == audioDevMap_.end()) {
308 DHLOGD("Device not register.");
309 return;
310 }
311 CHECK_NULL_VOID(dev->second);
312 dev->second->SleepAudioDev();
313 audioDevMap_.erase(devId);
314 }
315
LoadAVReceiverEngineProvider()316 int32_t DAudioSinkManager::LoadAVReceiverEngineProvider()
317 {
318 DHLOGI("LoadAVReceiverEngineProvider enter");
319 if (RECEIVER_SO_NAME.length() > PATH_MAX) {
320 DHLOGE("File open failed");
321 return ERR_DH_AUDIO_NULLPTR;
322 }
323 pRHandler_ = dlopen(RECEIVER_SO_NAME.c_str(), RTLD_LAZY | RTLD_NODELETE);
324 CHECK_NULL_RETURN(pRHandler_, ERR_DH_AUDIO_NULLPTR);
325
326 AVTransProviderClass getEngineFactoryFunc = (AVTransProviderClass)dlsym(pRHandler_,
327 GET_RECEIVER_PROVIDER_FUNC.c_str());
328 if (getEngineFactoryFunc == nullptr) {
329 DHLOGE("av transport engine factory function handler is null, failed reason : %{public}s", dlerror());
330 dlclose(pRHandler_);
331 pRHandler_ = nullptr;
332 return ERR_DH_AUDIO_NULLPTR;
333 }
334 rcvProviderPtr_ = getEngineFactoryFunc(OWNER_NAME_D_SPEAKER);
335 DHLOGI("LoadAVReceiverEngineProvider success.");
336 return DH_SUCCESS;
337 }
338
UnloadAVReceiverEngineProvider()339 int32_t DAudioSinkManager::UnloadAVReceiverEngineProvider()
340 {
341 DHLOGI("UnloadAVReceiverEngineProvider");
342 if (pRHandler_ != nullptr) {
343 dlclose(pRHandler_);
344 pRHandler_ = nullptr;
345 }
346 return DH_SUCCESS;
347 }
348
LoadAVSenderEngineProvider()349 int32_t DAudioSinkManager::LoadAVSenderEngineProvider()
350 {
351 DHLOGI("LoadAVSenderEngineProvider enter");
352 if (SENDER_SO_NAME.length() > PATH_MAX) {
353 DHLOGE("File open failed");
354 return ERR_DH_AUDIO_NULLPTR;
355 }
356 pSHandler_ = dlopen(SENDER_SO_NAME.c_str(), RTLD_LAZY | RTLD_NODELETE);
357 CHECK_NULL_RETURN(pSHandler_, ERR_DH_AUDIO_NULLPTR);
358
359 AVTransProviderClass getEngineFactoryFunc = (AVTransProviderClass)dlsym(pSHandler_,
360 GET_SENDER_PROVIDER_FUNC.c_str());
361 if (getEngineFactoryFunc == nullptr) {
362 DHLOGE("av transport engine factory function handler is null, failed reason : %{public}s", dlerror());
363 dlclose(pSHandler_);
364 pSHandler_ = nullptr;
365 return ERR_DH_AUDIO_NULLPTR;
366 }
367 sendProviderPtr_ = getEngineFactoryFunc(OWNER_NAME_D_MIC);
368 return DH_SUCCESS;
369 }
370
UnloadAVSenderEngineProvider()371 int32_t DAudioSinkManager::UnloadAVSenderEngineProvider()
372 {
373 DHLOGI("UnloadAVSenderEngineProvider enter");
374 if (pSHandler_ != nullptr) {
375 dlclose(pSHandler_);
376 pSHandler_ = nullptr;
377 }
378 return DH_SUCCESS;
379 }
380
SetChannelState(const std::string & content)381 void DAudioSinkManager::SetChannelState(const std::string &content)
382 {
383 DHLOGI("The channel state belong to %{public}s.", content.c_str());
384 if (content.find(OWNER_NAME_D_SPEAKER) != content.npos) {
385 channelState_ = ChannelState::SPK_CONTROL_OPENED;
386 } else if (content.find(OWNER_NAME_D_MIC) != content.npos) {
387 channelState_ = ChannelState::MIC_CONTROL_OPENED;
388 }
389 }
390
OnProviderEvent(const AVTransEvent & event)391 int32_t EngineProviderListener::OnProviderEvent(const AVTransEvent &event)
392 {
393 DHLOGI("On event :%{public}d, eventContent: %{public}s.", event.type, event.content.c_str());
394 if (event.type == EventType::EVENT_CHANNEL_OPENED) {
395 DHLOGI("Received control channel opened event, create audio device for peerDevId=%{public}s, "
396 "content=%{public}s.", GetAnonyString(event.peerDevId).c_str(), event.content.c_str());
397 DAudioSinkManager::GetInstance().SetChannelState(event.content);
398 DAudioSinkManager::GetInstance().CreateAudioDevice(event.peerDevId);
399 } else if (event.type == EventType::EVENT_CHANNEL_CLOSED) {
400 DHLOGI("Received control channel closed event, clear audio device for peerDevId=%{public}s",
401 GetAnonyString(event.peerDevId).c_str());
402 std::string eventStr = event.content;
403 DAudioSinkManager::GetInstance().NotifyEvent(event.peerDevId, DISABLE_DEVICE, eventStr);
404 } else {
405 DHLOGE("Invaild event type.");
406 }
407 return DH_SUCCESS;
408 }
409
OnCtrlChannelEvent(const AVTransEvent & event)410 void CtrlChannelListener::OnCtrlChannelEvent(const AVTransEvent &event)
411 {
412 DHLOGI("OnCtrlChannelEvent :%{public}d, eventContent: %{public}s.", event.type, event.content.c_str());
413 if (event.type == EventType::EVENT_CHANNEL_OPENED) {
414 DHLOGI("Received control channel opened event, create audio device for peerDevId=%{public}s, "
415 "content=%{public}s.", GetAnonyString(event.peerDevId).c_str(), event.content.c_str());
416 DAudioSinkManager::GetInstance().SetChannelState(event.content);
417 DAudioSinkManager::GetInstance().CreateAudioDevice(event.peerDevId);
418 } else if (event.type == EventType::EVENT_CHANNEL_CLOSED) {
419 DHLOGI("Received control channel closed event, clear audio device for peerDevId=%{public}s",
420 GetAnonyString(event.peerDevId).c_str());
421 std::string eventStr = event.content;
422 DAudioSinkManager::GetInstance().NotifyEvent(event.peerDevId, DISABLE_DEVICE, eventStr);
423 } else {
424 DHLOGE("Invaild event type.");
425 }
426 }
427
PauseDistributedHardware(const std::string & networkId)428 int32_t DAudioSinkManager::PauseDistributedHardware(const std::string &networkId)
429 {
430 std::lock_guard<std::mutex> lock(devMapMutex_);
431 if (audioDevMap_.find(networkId) != audioDevMap_.end()) {
432 DHLOGI("Audio sink dev in map. devId: %{public}s.", GetAnonyString(networkId).c_str());
433 CHECK_NULL_RETURN(audioDevMap_[networkId], ERR_DH_AUDIO_NULLPTR);
434 audioDevMap_[networkId]->PauseDistributedHardware(networkId);
435 }
436 return DH_SUCCESS;
437 }
438
ResumeDistributedHardware(const std::string & networkId)439 int32_t DAudioSinkManager::ResumeDistributedHardware(const std::string &networkId)
440 {
441 std::lock_guard<std::mutex> lock(devMapMutex_);
442 if (audioDevMap_.find(networkId) != audioDevMap_.end()) {
443 DHLOGI("Audio sink dev in map. devId: %{public}s.", GetAnonyString(networkId).c_str());
444 CHECK_NULL_RETURN(audioDevMap_[networkId], ERR_DH_AUDIO_NULLPTR);
445 audioDevMap_[networkId]->ResumeDistributedHardware(networkId);
446 }
447 return DH_SUCCESS;
448 }
449
StopDistributedHardware(const std::string & networkId)450 int32_t DAudioSinkManager::StopDistributedHardware(const std::string &networkId)
451 {
452 std::lock_guard<std::mutex> lock(devMapMutex_);
453 if (audioDevMap_.find(networkId) != audioDevMap_.end()) {
454 DHLOGI("Audio sink dev in map. devId: %{public}s.", GetAnonyString(networkId).c_str());
455 CHECK_NULL_RETURN(audioDevMap_[networkId], ERR_DH_AUDIO_NULLPTR);
456 audioDevMap_[networkId]->StopDistributedHardware(networkId);
457 }
458 return DH_SUCCESS;
459 }
460
CheckDeviceSecurityLevel(const std::string & srcDeviceId,const std::string & dstDeviceId)461 bool DAudioSinkManager::CheckDeviceSecurityLevel(const std::string &srcDeviceId, const std::string &dstDeviceId)
462 {
463 DHLOGD("CheckDeviceSecurityLevel srcDeviceId %{public}s, dstDeviceId %{public}s.",
464 GetAnonyString(srcDeviceId).c_str(), GetAnonyString(dstDeviceId).c_str());
465 std::string srcUdid = GetUdidByNetworkId(srcDeviceId);
466 if (srcUdid.empty()) {
467 DHLOGE("src udid is empty");
468 return false;
469 }
470 std::string dstUdid = GetUdidByNetworkId(dstDeviceId);
471 if (dstUdid.empty()) {
472 DHLOGE("dst udid is empty");
473 return false;
474 }
475 DHLOGD("CheckDeviceSecurityLevel srcUdid %{public}s, dstUdid %{public}s.",
476 GetAnonyString(srcUdid).c_str(), GetAnonyString(dstUdid).c_str());
477 int32_t srcDeviceSecurityLevel = GetDeviceSecurityLevel(srcUdid);
478 int32_t dstDeviceSecurityLevel = GetDeviceSecurityLevel(dstUdid);
479 DHLOGD("SrcDeviceSecurityLevel, level is %{public}d", srcDeviceSecurityLevel);
480 DHLOGD("dstDeviceSecurityLevel, level is %{public}d", dstDeviceSecurityLevel);
481 if (srcDeviceSecurityLevel == DEFAULT_DEVICE_SECURITY_LEVEL ||
482 srcDeviceSecurityLevel < dstDeviceSecurityLevel) {
483 DHLOGE("The device security of source device is lower.");
484 return false;
485 }
486 return true;
487 }
488
GetDeviceSecurityLevel(const std::string & udid)489 int32_t DAudioSinkManager::GetDeviceSecurityLevel(const std::string &udid)
490 {
491 #ifdef DEVICE_SECURITY_LEVEL_ENABLE
492 DeviceIdentify devIdentify;
493 devIdentify.length = DEVICE_ID_MAX_LEN;
494 int32_t ret = memcpy_s(devIdentify.identity, DEVICE_ID_MAX_LEN, udid.c_str(), DEVICE_ID_MAX_LEN);
495 if (ret != DH_SUCCESS) {
496 DHLOGE("Str copy failed %{public}d", ret);
497 return DEFAULT_DEVICE_SECURITY_LEVEL;
498 }
499 DeviceSecurityInfo *info = nullptr;
500 ret = RequestDeviceSecurityInfo(&devIdentify, nullptr, &info);
501 if (ret != DH_SUCCESS) {
502 DHLOGE("Request device security info failed %{public}d", ret);
503 FreeDeviceSecurityInfo(info);
504 info = nullptr;
505 return DEFAULT_DEVICE_SECURITY_LEVEL;
506 }
507 #endif
508 int32_t level = 0;
509 #ifdef DEVICE_SECURITY_LEVEL_ENABLE
510 ret = GetDeviceSecurityLevelValue(info, &level);
511 DHLOGE("Get device security level, level is %{public}d", level);
512 FreeDeviceSecurityInfo(info);
513 info = nullptr;
514 if (ret != DH_SUCCESS) {
515 DHLOGE("Get device security level failed %{public}d", ret);
516 return DEFAULT_DEVICE_SECURITY_LEVEL;
517 }
518 #endif
519 return level;
520 }
521
GetUdidByNetworkId(const std::string & networkId)522 std::string DAudioSinkManager::GetUdidByNetworkId(const std::string &networkId)
523 {
524 if (networkId.empty()) {
525 DHLOGE("networkId is empty!");
526 return "";
527 }
528 int32_t ret = DeviceManager::GetInstance().InitDeviceManager(PKG_NAME, initCallback_);
529 if (ret != ERR_OK) {
530 DHLOGE("InitDeviceManager failed ret = %{public}d", ret);
531 }
532 std::string udid = "";
533 ret = DeviceManager::GetInstance().GetUdidByNetworkId(PKG_NAME, networkId, udid);
534 if (ret != ERR_OK) {
535 DHLOGE("GetUdidByNetworkId failed ret = %{public}d", ret);
536 return "";
537 }
538 return udid;
539 }
540
VerifySecurityLevel(const std::string & devId)541 int32_t DAudioSinkManager::VerifySecurityLevel(const std::string &devId)
542 {
543 std::string subType = "mic";
544 CHECK_NULL_RETURN(ipcSinkCallback_, ERR_DH_AUDIO_FAILED);
545 int32_t ret = ipcSinkCallback_->OnNotifyResourceInfo(ResourceEventType::EVENT_TYPE_QUERY_RESOURCE, subType, devId,
546 isSensitive_, isSameAccount_);
547 if (ret != DH_SUCCESS) {
548 DHLOGE("Query resource failed, ret: %{public}d", ret);
549 return ret;
550 }
551 DHLOGD("VerifySecurityLevel isSensitive: %{public}d, isSameAccount: %{public}d", isSensitive_, isSameAccount_);
552 if (isSensitive_ && !isSameAccount_) {
553 DHLOGE("Privacy resource must be logged in with same account.");
554 return ERR_DH_AUDIO_FAILED;
555 }
556
557 if (isCheckSecLevel_) {
558 std::string sinkDevId = "";
559 ret = GetLocalDeviceNetworkId(sinkDevId);
560 if (ret != DH_SUCCESS) {
561 DHLOGE("GetLocalDeviceNetworkId failed, ret: %{public}d", ret);
562 return ret;
563 }
564 if (isSensitive_ && !CheckDeviceSecurityLevel(devId, sinkDevId)) {
565 DHLOGE("Check device security level failed!");
566 return ERR_DH_AUDIO_FAILED;
567 }
568 }
569 return DH_SUCCESS;
570 }
571
OnRemoteDied()572 void DeviceInitCallback::OnRemoteDied()
573 {
574 DHLOGI("DeviceInitCallback OnRemoteDied");
575 }
576 } // namespace DistributedHardware
577 } // namespace OHOS
578