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