1 /*
2  * Copyright (c) 2022-2023 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_source_manager.h"
17 
18 #include <dlfcn.h>
19 #include "if_system_ability_manager.h"
20 #include "iservice_registry.h"
21 #include "xcollie/watchdog.h"
22 
23 #include "daudio_constants.h"
24 #include "daudio_errorcode.h"
25 #include "daudio_log.h"
26 #include "daudio_util.h"
27 
28 #undef DH_LOG_TAG
29 #define DH_LOG_TAG "DAudioSourceManager"
30 
31 namespace OHOS {
32 namespace DistributedHardware {
33 namespace {
34 constexpr uint32_t MAX_DEVICE_ID_LENGTH = 200;
35 constexpr uint32_t MAX_DISTRIBUTED_HARDWARE_ID_LENGTH = 100;
36 constexpr uint32_t EVENT_MANAGER_ENABLE_DAUDIO = 11;
37 constexpr uint32_t EVENT_MANAGER_DISABLE_DAUDIO = 12;
38 }
39 IMPLEMENT_SINGLE_INSTANCE(DAudioSourceManager);
40 using AVTransProviderClass = IAVEngineProvider *(*)(const std::string &);
41 
42 const std::string SENDER_SO_NAME = "libdistributed_av_sender.z.so";
43 const std::string GET_SENDER_PROVIDER_FUNC = "GetAVSenderEngineProvider";
44 const std::string RECEIVER_SO_NAME = "libdistributed_av_receiver.z.so";
45 const std::string GET_RECEIVER_PROVIDER_FUNC = "GetAVReceiverEngineProvider";
46 
DAudioSourceManager()47 DAudioSourceManager::DAudioSourceManager()
48 {
49     DHLOGD("Distributed audio source manager constructed.");
50 }
51 
~DAudioSourceManager()52 DAudioSourceManager::~DAudioSourceManager()
53 {
54     if (devClearThread_.joinable()) {
55         devClearThread_.join();
56     }
57 
58     isHicollieRunning_.store(false);
59     if (listenThread_.joinable()) {
60         listenThread_.join();
61     }
62     DHLOGD("Distributed audio source manager destructed.");
63 }
64 
Init(const sptr<IDAudioIpcCallback> & callback)65 int32_t DAudioSourceManager::Init(const sptr<IDAudioIpcCallback> &callback)
66 {
67     DHLOGI("Init audio source manager.");
68     CHECK_NULL_RETURN(callback, ERR_DH_AUDIO_NULLPTR);
69     if (DAudioHdiHandler::GetInstance().InitHdiHandler() != DH_SUCCESS) {
70         DHLOGE("Init Hdi handler failed.");
71         return ERR_DH_AUDIO_FAILED;
72     }
73     if (GetLocalDeviceNetworkId(localDevId_) != DH_SUCCESS) {
74         DHLOGE("Get local network id failed.");
75         return ERR_DH_AUDIO_FAILED;
76     }
77     {
78         std::lock_guard<std::mutex> lock(ipcCallbackMutex_);
79         ipcCallback_ = callback;
80         daudioMgrCallback_ = std::make_shared<DAudioSourceMgrCallback>();
81     }
82     int32_t ret = LoadAVSenderEngineProvider();
83     if (ret != DH_SUCCESS) {
84         DHLOGE("load av transport sender engine provider failed");
85         return ERR_DH_AUDIO_FAILED;
86     }
87     ret = LoadAVReceiverEngineProvider();
88     if (ret != DH_SUCCESS) {
89         DHLOGE("load av transport receiver engine provider failed.");
90         return ERR_DH_AUDIO_FAILED;
91     }
92     if (!isHicollieRunning_.load()) {
93         isHicollieRunning_.store(true);
94         listenThread_ = std::thread([this]() { this->ListenAudioDev(); });
95         if (pthread_setname_np(listenThread_.native_handle(), LISTEN_THREAD) != DH_SUCCESS) {
96             DHLOGE("Dev clear thread setname failed.");
97         }
98     }
99     // init event handler
100     auto runner = AppExecFwk::EventRunner::Create(true);
101     CHECK_NULL_RETURN(runner, ERR_DH_AUDIO_NULLPTR);
102     handler_ = std::make_shared<DAudioSourceManager::SourceManagerHandler>(runner);
103     DHLOGD("Init DAudioManager successfuly.");
104     return DH_SUCCESS;
105 }
106 
UnInit()107 int32_t DAudioSourceManager::UnInit()
108 {
109     DHLOGI("Uninit audio source manager.");
110     UnloadAVReceiverEngineProvider();
111     UnloadAVSenderEngineProvider();
112     {
113         std::lock_guard<std::mutex> lock(devMapMtx_);
114         for (auto iter = audioDevMap_.begin(); iter != audioDevMap_.end(); iter++) {
115             if (iter->second.dev == nullptr) {
116                 continue;
117             }
118             iter->second.dev->SleepAudioDev();
119         }
120         audioDevMap_.clear();
121         DHLOGI("Audio dev map cleared.");
122     }
123     if (devClearThread_.joinable()) {
124         devClearThread_.join();
125     }
126 
127     isHicollieRunning_.store(false);
128     if (listenThread_.joinable()) {
129         listenThread_.join();
130     }
131 
132     if (handler_ != nullptr) {
133         while (!handler_->IsIdle()) {
134             DHLOGD("manager handler is running, wait for idle.");
135             usleep(WAIT_HANDLER_IDLE_TIME_US);
136         }
137     }
138     ipcCallback_ = nullptr;
139     daudioMgrCallback_ = nullptr;
140     if (DAudioHdiHandler::GetInstance().UninitHdiHandler() != DH_SUCCESS) {
141         DHLOGE("Uninit Hdi handler failed.");
142         return ERR_DH_AUDIO_FAILED;
143     }
144 
145     DHLOGD("Uninit audio source manager exit.");
146     return DH_SUCCESS;
147 }
148 
CheckParams(const std::string & devId,const std::string & dhId)149 static bool CheckParams(const std::string &devId, const std::string &dhId)
150 {
151     DHLOGD("Checking params of daudio.");
152     if (devId.empty() || dhId.empty() ||
153         devId.size() > MAX_DEVICE_ID_LENGTH || dhId.size() > MAX_DISTRIBUTED_HARDWARE_ID_LENGTH) {
154         return false;
155     }
156     return true;
157 }
158 
EnableDAudio(const std::string & devId,const std::string & dhId,const std::string & version,const std::string & attrs,const std::string & reqId)159 int32_t DAudioSourceManager::EnableDAudio(const std::string &devId, const std::string &dhId,
160     const std::string &version, const std::string &attrs, const std::string &reqId)
161 {
162     DHLOGI("Enable distributed audio, devId: %{public}s, dhId: %{public}s, version: %{public}s, reqId: %{public}s.",
163         GetAnonyString(devId).c_str(), dhId.c_str(), version.c_str(), reqId.c_str());
164     CHECK_NULL_RETURN(handler_, ERR_DH_AUDIO_NULLPTR);
165 
166     cJSON *jParam = cJSON_CreateObject();
167     CHECK_NULL_RETURN(jParam, ERR_DH_AUDIO_NULLPTR);
168     cJSON_AddStringToObject(jParam, KEY_DEV_ID, devId.c_str());
169     cJSON_AddStringToObject(jParam, KEY_DH_ID, dhId.c_str());
170     cJSON_AddStringToObject(jParam, KEY_VERSION, version.c_str());
171     cJSON_AddStringToObject(jParam, KEY_ATTRS, attrs.c_str());
172     cJSON_AddStringToObject(jParam, KEY_REQID, reqId.c_str());
173     char *jsonString = cJSON_PrintUnformatted(jParam);
174     if (jsonString == nullptr) {
175         DHLOGE("Failed to create JSON data");
176         cJSON_Delete(jParam);
177         return ERR_DH_AUDIO_NULLPTR;
178     }
179     auto eventParam = std::make_shared<std::string>(jsonString);
180     auto msgEvent = AppExecFwk::InnerEvent::Get(EVENT_MANAGER_ENABLE_DAUDIO, eventParam, 0);
181     if (!handler_->SendEvent(msgEvent, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE)) {
182         DHLOGE("Send event failed.");
183         cJSON_Delete(jParam);
184         cJSON_free(jsonString);
185         return ERR_DH_AUDIO_FAILED;
186     }
187     cJSON_Delete(jParam);
188     cJSON_free(jsonString);
189     DHLOGD("Enable audio task generate successfully.");
190     return DH_SUCCESS;
191 }
192 
DoEnableDAudio(const std::string & args)193 int32_t DAudioSourceManager::DoEnableDAudio(const std::string &args)
194 {
195     std::string devId = ParseStringFromArgs(args, KEY_DEV_ID);
196     std::string dhId = ParseStringFromArgs(args, KEY_DH_ID);
197     std::string version = ParseStringFromArgs(args, KEY_VERSION);
198     std::string attrs = ParseStringFromArgs(args, KEY_ATTRS);
199     std::string reqId = ParseStringFromArgs(args, KEY_REQID);
200     DHLOGI("Do Enable distributed audio, devId: %{public}s, dhId: %{public}s, version:%{public}s, reqId:%{public}s.",
201         GetAnonyString(devId).c_str(), dhId.c_str(), version.c_str(), reqId.c_str());
202     if (!CheckParams(devId, dhId) || attrs.empty()) {
203         DHLOGE("Enable params are incorrect.");
204         return ERR_DH_AUDIO_FAILED;
205     }
206     std::shared_ptr<DAudioSourceDev> sourceDev = nullptr;
207     {
208         std::lock_guard<std::mutex> lock(devMapMtx_);
209         auto device = audioDevMap_.find(devId);
210         if (device == audioDevMap_.end()) {
211             if (CreateAudioDevice(devId) != DH_SUCCESS) {
212                 return ERR_DH_AUDIO_FAILED;
213             }
214         }
215         audioDevMap_[devId].ports[dhId] = reqId;
216         sourceDev = audioDevMap_[devId].dev;
217     }
218     DHLOGD("Call source dev to enable daudio.");
219     if (sourceDev == nullptr) {
220         DHLOGE("Source dev is nullptr.");
221         return ERR_DH_AUDIO_FAILED;
222     }
223     int32_t result = sourceDev->EnableDAudio(dhId, attrs);
224     return OnEnableDAudio(devId, dhId, result);
225 }
226 
DisableDAudio(const std::string & devId,const std::string & dhId,const std::string & reqId)227 int32_t DAudioSourceManager::DisableDAudio(const std::string &devId, const std::string &dhId, const std::string &reqId)
228 {
229     DHLOGI("Disable distributed audio, devId: %{public}s, dhId: %{public}s, reqId: %{public}s.",
230         GetAnonyString(devId).c_str(), dhId.c_str(), reqId.c_str());
231     CHECK_NULL_RETURN(handler_, ERR_DH_AUDIO_NULLPTR);
232     cJSON *jParam = cJSON_CreateObject();
233     CHECK_NULL_RETURN(jParam, ERR_DH_AUDIO_NULLPTR);
234     cJSON_AddStringToObject(jParam, KEY_DEV_ID, devId.c_str());
235     cJSON_AddStringToObject(jParam, KEY_DH_ID, dhId.c_str());
236     cJSON_AddStringToObject(jParam, KEY_REQID, reqId.c_str());
237     char *jsonString = cJSON_PrintUnformatted(jParam);
238     if (jsonString == nullptr) {
239         DHLOGE("Failed to create JSON data");
240         cJSON_Delete(jParam);
241         return ERR_DH_AUDIO_NULLPTR;
242     }
243     auto eventParam = std::make_shared<std::string>(jsonString);
244     auto msgEvent = AppExecFwk::InnerEvent::Get(EVENT_MANAGER_DISABLE_DAUDIO, eventParam, 0);
245     if (!handler_->SendEvent(msgEvent, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE)) {
246         DHLOGE("Send event failed.");
247         cJSON_Delete(jParam);
248         cJSON_free(jsonString);
249         return ERR_DH_AUDIO_FAILED;
250     }
251     cJSON_Delete(jParam);
252     cJSON_free(jsonString);
253     DHLOGD("Disable audio task generate successfully.");
254     return DH_SUCCESS;
255 }
256 
DoDisableDAudio(const std::string & args)257 int32_t DAudioSourceManager::DoDisableDAudio(const std::string &args)
258 {
259     std::string devId = ParseStringFromArgs(args, KEY_DEV_ID);
260     std::string dhId = ParseStringFromArgs(args, KEY_DH_ID);
261     std::string reqId = ParseStringFromArgs(args, KEY_REQID);
262     DHLOGI("Do Disable distributed audio, devId: %{public}s, dhId: %{public}s, reqId:%{public}s.",
263         GetAnonyString(devId).c_str(), dhId.c_str(), reqId.c_str());
264     if (!CheckParams(devId, dhId)) {
265         DHLOGE("Disable params are incorrect.");
266         return ERR_DH_AUDIO_FAILED;
267     }
268     std::shared_ptr<DAudioSourceDev> sourceDev = nullptr;
269     {
270         std::lock_guard<std::mutex> lock(devMapMtx_);
271         auto device = audioDevMap_.find(devId);
272         if (device == audioDevMap_.end()) {
273             DHLOGE("Audio device not exist.");
274             return ERR_DH_AUDIO_SA_DEVICE_NOT_EXIST;
275         }
276         CHECK_NULL_RETURN(audioDevMap_[devId].dev, DH_SUCCESS);
277         audioDevMap_[devId].ports[dhId] = reqId;
278         sourceDev = audioDevMap_[devId].dev;
279     }
280     DHLOGD("Call source dev to disable daudio.");
281     int32_t result = sourceDev->DisableDAudio(dhId);
282     return OnDisableDAudio(devId, dhId, result);
283 }
284 
HandleDAudioNotify(const std::string & devId,const std::string & dhId,const int32_t eventType,const std::string & eventContent)285 int32_t DAudioSourceManager::HandleDAudioNotify(const std::string &devId, const std::string &dhId,
286     const int32_t eventType, const std::string &eventContent)
287 {
288     DHLOGD("Receive audio event from devId: %{public}s, event type: %{public}d. event content: %{public}s.",
289         GetAnonyString(devId).c_str(), eventType, eventContent.c_str());
290     if (eventContent.length() > DAUDIO_MAX_JSON_LEN || eventContent.empty()) {
291         return ERR_DH_AUDIO_FAILED;
292     }
293 
294     // now ctrl channel is also goto here, please sure here not crash.
295     cJSON *jParam = cJSON_Parse(eventContent.c_str());
296     if (CJsonParamCheck(jParam, { KEY_RANDOM_TASK_CODE })) {
297         DHLOGD("Receive audio notify from sink, random task code: %{public}s",
298             cJSON_GetObjectItemCaseSensitive(jParam, KEY_RANDOM_TASK_CODE)->valuestring);
299     }
300 
301     std::shared_ptr<DAudioSourceDev> sourceDev = nullptr;
302     {
303         std::lock_guard<std::mutex> lock(devMapMtx_);
304         auto device = audioDevMap_.find(devId);
305         if (device == audioDevMap_.end()) {
306             DHLOGE("Audio device not exist.");
307             cJSON_Delete(jParam);
308             return ERR_DH_AUDIO_SA_DEVICE_NOT_EXIST;
309         }
310         sourceDev = audioDevMap_[devId].dev;
311     }
312 
313     AudioEvent audioEvent(eventType, eventContent);
314     sourceDev->NotifyEvent(audioEvent);
315     cJSON_Delete(jParam);
316     return DH_SUCCESS;
317 }
318 
DAudioNotify(const std::string & devId,const std::string & dhId,const int32_t eventType,const std::string & eventContent)319 int32_t DAudioSourceManager::DAudioNotify(const std::string &devId, const std::string &dhId, const int32_t eventType,
320     const std::string &eventContent)
321 {
322     DHLOGD("Distributed audio notify, devId: %{public}s, dhId: %{public}s, eventType: %{public}d.",
323         GetAnonyString(devId).c_str(), dhId.c_str(), eventType);
324     {
325         std::lock_guard<std::mutex> lck(remoteSvrMutex_);
326         auto sinkProxy = sinkServiceMap_.find(devId);
327         if (sinkProxy != sinkServiceMap_.end()) {
328             if (sinkProxy->second != nullptr) {
329                 sinkProxy->second->DAudioNotify(localDevId_, dhId, eventType, eventContent);
330                 return DH_SUCCESS;
331             }
332         }
333     }
334 
335     auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
336     CHECK_NULL_RETURN(samgr, ERR_DH_AUDIO_NULLPTR);
337     auto remoteObject = samgr->GetSystemAbility(DISTRIBUTED_HARDWARE_AUDIO_SINK_SA_ID, devId);
338     CHECK_NULL_RETURN(remoteObject, ERR_DH_AUDIO_NULLPTR);
339     sptr<IDAudioSink> remoteSvrProxy = iface_cast<IDAudioSink>(remoteObject);
340     CHECK_NULL_RETURN(remoteSvrProxy, ERR_DH_AUDIO_NULLPTR);
341     {
342         std::lock_guard<std::mutex> lck(remoteSvrMutex_);
343         sinkServiceMap_[devId] = remoteSvrProxy;
344         remoteSvrProxy->DAudioNotify(localDevId_, dhId, eventType, eventContent);
345     }
346     return DH_SUCCESS;
347 }
348 
OnEnableDAudio(const std::string & devId,const std::string & dhId,const int32_t result)349 int32_t DAudioSourceManager::OnEnableDAudio(const std::string &devId, const std::string &dhId, const int32_t result)
350 {
351     DHLOGI("On enable distributed audio devId: %{public}s, dhId: %{public}s, ret: %{public}d.",
352         GetAnonyString(devId).c_str(), dhId.c_str(), result);
353     std::string reqId = GetRequestId(devId, dhId);
354     if (reqId.empty()) {
355         return ERR_DH_AUDIO_FAILED;
356     }
357     if (result != DH_SUCCESS) {
358         DeleteAudioDevice(devId, dhId);
359     }
360 
361     CHECK_NULL_RETURN(ipcCallback_, ERR_DH_AUDIO_NULLPTR);
362     return ipcCallback_->OnNotifyRegResult(devId, dhId, reqId, result, "");
363 }
364 
OnHardwareStateChanged(const std::string & devId,const std::string & dhId,const int32_t state)365 int32_t DAudioSourceManager::OnHardwareStateChanged(const std::string &devId, const std::string &dhId,
366     const int32_t state)
367 {
368     DHLOGI("On distributed hardware state changed devId: %{public}s, dhId: %{public}s, ret: %{public}d.",
369         GetAnonyString(devId).c_str(), dhId.c_str(), state);
370 
371     CHECK_NULL_RETURN(ipcCallback_, ERR_DH_AUDIO_NULLPTR);
372     return ipcCallback_->OnHardwareStateChanged(devId, dhId, state);
373 }
374 
OnDataSyncTrigger(const std::string & devId)375 int32_t DAudioSourceManager::OnDataSyncTrigger(const std::string &devId)
376 {
377     DHLOGI("On data sync trigger devId: %{public}s.", GetAnonyString(devId).c_str());
378 
379     CHECK_NULL_RETURN(ipcCallback_, ERR_DH_AUDIO_NULLPTR);
380     return ipcCallback_->OnDataSyncTrigger(devId);
381 }
382 
OnDisableDAudio(const std::string & devId,const std::string & dhId,const int32_t result)383 int32_t DAudioSourceManager::OnDisableDAudio(const std::string &devId, const std::string &dhId, const int32_t result)
384 {
385     DHLOGI("On disable distributed audio devId: %{public}s, dhId: %{public}s, ret: %{public}d.",
386         GetAnonyString(devId).c_str(), dhId.c_str(), result);
387     std::string reqId = GetRequestId(devId, dhId);
388     if (reqId.empty()) {
389         return ERR_DH_AUDIO_FAILED;
390     }
391     if (result == DH_SUCCESS) {
392         DeleteAudioDevice(devId, dhId);
393     }
394 
395     CHECK_NULL_RETURN(ipcCallback_, ERR_DH_AUDIO_NULLPTR);
396     return ipcCallback_->OnNotifyUnregResult(devId, dhId, reqId, result, "");
397 }
398 
CreateAudioDevice(const std::string & devId)399 int32_t DAudioSourceManager::CreateAudioDevice(const std::string &devId)
400 {
401     DHLOGI("Create audio device.");
402     auto sourceDev = std::make_shared<DAudioSourceDev>(devId, daudioMgrCallback_);
403     if (sourceDev->AwakeAudioDev() != DH_SUCCESS) {
404         DHLOGE("Create new audio device failed.");
405         return ERR_DH_AUDIO_FAILED;
406     }
407     AudioDevice device = { devId, sourceDev };
408     audioDevMap_[devId] = device;
409     return DH_SUCCESS;
410 }
411 
DeleteAudioDevice(const std::string & devId,const std::string & dhId)412 void DAudioSourceManager::DeleteAudioDevice(const std::string &devId, const std::string &dhId)
413 {
414     DHLOGD("Delete audio device, devId = %{public}s, dhId = %{public}s.", GetAnonyString(devId).c_str(), dhId.c_str());
415     {
416         std::lock_guard<std::mutex> lock(devMapMtx_);
417         audioDevMap_[devId].ports.erase(dhId);
418         if (!audioDevMap_[devId].ports.empty()) {
419             DHLOGI("audioDevMap_[devId].ports is not empty");
420             return;
421         }
422     }
423     if (devClearThread_.joinable()) {
424         devClearThread_.join();
425     }
426     DHLOGD("audioDevMap_[devId].ports is empty");
427     devClearThread_ = std::thread([this, devId]() { this->ClearAudioDev(devId); });
428     if (pthread_setname_np(devClearThread_.native_handle(), DEVCLEAR_THREAD) != DH_SUCCESS) {
429         DHLOGE("Dev clear thread setname failed.");
430     }
431 }
432 
GetRequestId(const std::string & devId,const std::string & dhId)433 std::string DAudioSourceManager::GetRequestId(const std::string &devId, const std::string &dhId)
434 {
435     std::lock_guard<std::mutex> lock(devMapMtx_);
436     auto dev = audioDevMap_.find(devId);
437     if (dev == audioDevMap_.end()) {
438         DHLOGE("Audio device not exist.");
439         return "";
440     }
441     auto port = audioDevMap_[devId].ports.find(dhId);
442     if (port == audioDevMap_[devId].ports.end()) {
443         DHLOGE("Audio port not exist.");
444         return "";
445     }
446     return port->second;
447 }
448 
ClearAudioDev(const std::string & devId)449 void DAudioSourceManager::ClearAudioDev(const std::string &devId)
450 {
451     DHLOGI("ClearAudioDev, devId = %{public}s.", GetAnonyString(devId).c_str());
452     std::lock_guard<std::mutex> lock(devMapMtx_);
453     if (audioDevMap_[devId].ports.empty()) {
454         DHLOGI("audioDevMap_[devId].ports is empty.");
455         CHECK_NULL_VOID(audioDevMap_[devId].dev);
456         audioDevMap_[devId].dev->SleepAudioDev();
457         DHLOGI("back from SleepAudioDev.");
458         audioDevMap_.erase(devId);
459     }
460 }
461 
RestoreThreadStatus()462 void DAudioSourceManager::RestoreThreadStatus()
463 {
464     std::lock_guard<std::mutex> lock(devMapMtx_);
465     if (!audioDevMap_.empty()) {
466         for (auto &iter : audioDevMap_) {
467             CHECK_NULL_VOID(iter.second.dev);
468             iter.second.dev->SetThreadStatusFlag(true);
469         }
470     }
471 }
472 
ListenAudioDev()473 void DAudioSourceManager::ListenAudioDev()
474 {
475     auto taskFunc = [this]() {
476         std::lock_guard<std::mutex> lock(devMapMtx_);
477         for (auto &iter : audioDevMap_) {
478             CHECK_NULL_VOID(iter.second.dev);
479             if (iter.second.dev->GetThreadStatusFlag()) {
480                 iter.second.dev->SetThreadStatusFlag(false);
481             } else {
482                 DHLOGE("Exit the current process hicollie");
483                 _Exit(0);
484             }
485         }
486     };
487     OHOS::HiviewDFX::Watchdog::GetInstance().RunPeriodicalTask("SourceService", taskFunc,
488         WATCHDOG_INTERVAL_TIME, WATCHDOG_DELAY_TIME);
489 
490     while (isHicollieRunning_.load()) {
491         {
492             std::lock_guard<std::mutex> lock(devMapMtx_);
493             RestoreThreadStatus();
494         }
495         usleep(SLEEP_TIME);
496     }
497 }
498 
LoadAVSenderEngineProvider()499 int32_t DAudioSourceManager::LoadAVSenderEngineProvider()
500 {
501     DHLOGI("LoadAVSenderEngineProvider enter");
502     if (SENDER_SO_NAME.length() > PATH_MAX) {
503         DHLOGE("File open failed");
504         return ERR_DH_AUDIO_NULLPTR;
505     }
506     pSHandler_ = dlopen(SENDER_SO_NAME.c_str(), RTLD_LAZY | RTLD_NODELETE);
507     CHECK_NULL_RETURN(pSHandler_, ERR_DH_AUDIO_NULLPTR);
508     AVTransProviderClass getEngineFactoryFunc = (AVTransProviderClass)dlsym(pSHandler_,
509         GET_SENDER_PROVIDER_FUNC.c_str());
510     if (getEngineFactoryFunc == nullptr) {
511         DHLOGE("av transport engine factory function handler is null, failed reason : %{public}s", dlerror());
512         dlclose(pSHandler_);
513         pSHandler_ = nullptr;
514         return ERR_DH_AUDIO_NULLPTR;
515     }
516     sendProviderPtr_ = getEngineFactoryFunc(OWNER_NAME_D_SPEAKER);
517     DHLOGD("LoadAVSenderEngineProvider exit");
518     return DH_SUCCESS;
519 }
520 
UnloadAVSenderEngineProvider()521 int32_t DAudioSourceManager::UnloadAVSenderEngineProvider()
522 {
523     DHLOGI("UnloadAVSenderEngineProvider enter");
524     if (pSHandler_ != nullptr) {
525         dlclose(pSHandler_);
526         pSHandler_ = nullptr;
527     }
528     sendProviderPtr_ = nullptr;
529     return DH_SUCCESS;
530 }
531 
LoadAVReceiverEngineProvider()532 int32_t DAudioSourceManager::LoadAVReceiverEngineProvider()
533 {
534     DHLOGI("LoadAVReceiverEngineProvider enter");
535     if (RECEIVER_SO_NAME.length() > PATH_MAX) {
536         DHLOGE("File canonicalization failed");
537         return ERR_DH_AUDIO_NULLPTR;
538     }
539     pRHandler_ = dlopen(RECEIVER_SO_NAME.c_str(), RTLD_LAZY | RTLD_NODELETE);
540     CHECK_NULL_RETURN(pRHandler_, ERR_DH_AUDIO_NULLPTR);
541     AVTransProviderClass getEngineFactoryFunc = (AVTransProviderClass)dlsym(pRHandler_,
542         GET_RECEIVER_PROVIDER_FUNC.c_str());
543     if (getEngineFactoryFunc == nullptr) {
544         DHLOGE("av transport engine factory function handler is null, failed reason : %{public}s", dlerror());
545         dlclose(pRHandler_);
546         pRHandler_ = nullptr;
547         return ERR_DH_AUDIO_NULLPTR;
548     }
549     rcvProviderPtr_ = getEngineFactoryFunc(OWNER_NAME_D_MIC);
550     DHLOGD("LoadAVReceiverEngineProvider success");
551     return DH_SUCCESS;
552 }
553 
UnloadAVReceiverEngineProvider()554 int32_t DAudioSourceManager::UnloadAVReceiverEngineProvider()
555 {
556     DHLOGI("UnloadAVReceiverEngineProvider");
557     if (pRHandler_ != nullptr) {
558         dlclose(pRHandler_);
559         pRHandler_ = nullptr;
560     }
561     return DH_SUCCESS;
562 }
563 
getSenderProvider()564 IAVEngineProvider *DAudioSourceManager::getSenderProvider()
565 {
566     return sendProviderPtr_;
567 }
568 
getReceiverProvider()569 IAVEngineProvider *DAudioSourceManager::getReceiverProvider()
570 {
571     return rcvProviderPtr_;
572 }
573 
SourceManagerHandler(const std::shared_ptr<AppExecFwk::EventRunner> & runner)574 DAudioSourceManager::SourceManagerHandler::SourceManagerHandler(const std::shared_ptr<AppExecFwk::EventRunner>
575     &runner) : AppExecFwk::EventHandler(runner)
576 {
577     DHLOGD("Event handler is constructing.");
578     mapEventFuncs_[EVENT_MANAGER_ENABLE_DAUDIO] = &DAudioSourceManager::SourceManagerHandler::EnableDAudioCallback;
579     mapEventFuncs_[EVENT_MANAGER_DISABLE_DAUDIO] = &DAudioSourceManager::SourceManagerHandler::DisableDAudioCallback;
580 }
581 
~SourceManagerHandler()582 DAudioSourceManager::SourceManagerHandler::~SourceManagerHandler() {}
583 
ProcessEvent(const AppExecFwk::InnerEvent::Pointer & event)584 void DAudioSourceManager::SourceManagerHandler::ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event)
585 {
586     CHECK_NULL_VOID(event);
587     DHLOGI("Event Id=%{public}d.", event->GetInnerEventId());
588     switch (event->GetInnerEventId()) {
589         case EVENT_MANAGER_ENABLE_DAUDIO:
590             EnableDAudioCallback(event);
591             break;
592         case EVENT_MANAGER_DISABLE_DAUDIO:
593             DisableDAudioCallback(event);
594             break;
595         default:
596             DHLOGE("Event Id is invalid. %{public}d.", event->GetInnerEventId());
597             break;
598     }
599 }
600 
EnableDAudioCallback(const AppExecFwk::InnerEvent::Pointer & event)601 void DAudioSourceManager::SourceManagerHandler::EnableDAudioCallback(const AppExecFwk::InnerEvent::Pointer &event)
602 {
603     CHECK_NULL_VOID(event);
604     std::string eventParam;
605     if (GetEventParam(event, eventParam) != DH_SUCCESS) {
606         DHLOGE("Failed to get event parameters.");
607         return;
608     }
609     DAudioSourceManager::GetInstance().DoEnableDAudio(eventParam);
610 }
611 
DisableDAudioCallback(const AppExecFwk::InnerEvent::Pointer & event)612 void DAudioSourceManager::SourceManagerHandler::DisableDAudioCallback(const AppExecFwk::InnerEvent::Pointer &event)
613 {
614     CHECK_NULL_VOID(event);
615     std::string eventParam;
616     if (GetEventParam(event, eventParam) != DH_SUCCESS) {
617         DHLOGE("Failed to get event parameters.");
618         return;
619     }
620     DHLOGD("Disable audio device, param:%{public}s.", eventParam.c_str());
621     DAudioSourceManager::GetInstance().DoDisableDAudio(eventParam);
622 }
623 
GetEventParam(const AppExecFwk::InnerEvent::Pointer & event,std::string & eventParam)624 int32_t DAudioSourceManager::SourceManagerHandler::GetEventParam(const AppExecFwk::InnerEvent::Pointer &event,
625     std::string &eventParam)
626 {
627     CHECK_NULL_RETURN(event, ERR_DH_AUDIO_NULLPTR);
628     auto jsonString = event->GetSharedObject<std::string>().get();
629     CHECK_NULL_RETURN(jsonString, ERR_DH_AUDIO_NULLPTR);
630     eventParam = *jsonString;
631     return DH_SUCCESS;
632 }
633 } // DistributedHardware
634 } // OHOS
635