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