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