• 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     int32_t result = sourceDev->EnableDAudio(dhId, attrs);
226     return OnEnableDAudio(devId, dhId, result);
227 }
228 
DisableDAudio(const std::string & devId,const std::string & dhId,const std::string & reqId)229 int32_t DAudioSourceManager::DisableDAudio(const std::string &devId, const std::string &dhId, const std::string &reqId)
230 {
231     DHLOGI("Disable distributed audio, devId: %{public}s, dhId: %{public}s, reqId: %{public}s.",
232         GetAnonyString(devId).c_str(), dhId.c_str(), reqId.c_str());
233     CHECK_NULL_RETURN(handler_, ERR_DH_AUDIO_NULLPTR);
234     cJSON *jParam = cJSON_CreateObject();
235     CHECK_NULL_RETURN(jParam, ERR_DH_AUDIO_NULLPTR);
236     cJSON_AddStringToObject(jParam, KEY_DEV_ID, devId.c_str());
237     cJSON_AddStringToObject(jParam, KEY_DH_ID, dhId.c_str());
238     cJSON_AddStringToObject(jParam, KEY_REQID, reqId.c_str());
239     char *jsonString = cJSON_PrintUnformatted(jParam);
240     if (jsonString == nullptr) {
241         DHLOGE("Failed to create JSON data");
242         cJSON_Delete(jParam);
243         return ERR_DH_AUDIO_NULLPTR;
244     }
245     auto eventParam = std::make_shared<std::string>(jsonString);
246     auto msgEvent = AppExecFwk::InnerEvent::Get(EVENT_MANAGER_DISABLE_DAUDIO, eventParam, 0);
247     if (!handler_->SendEvent(msgEvent, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE)) {
248         DHLOGE("Send event failed.");
249         cJSON_Delete(jParam);
250         cJSON_free(jsonString);
251         return ERR_DH_AUDIO_FAILED;
252     }
253     cJSON_Delete(jParam);
254     cJSON_free(jsonString);
255     DHLOGD("Disable audio task generate successfully.");
256     return DH_SUCCESS;
257 }
258 
DoDisableDAudio(const std::string & args)259 int32_t DAudioSourceManager::DoDisableDAudio(const std::string &args)
260 {
261     std::string devId = ParseStringFromArgs(args, KEY_DEV_ID);
262     std::string dhId = ParseStringFromArgs(args, KEY_DH_ID);
263     std::string reqId = ParseStringFromArgs(args, KEY_REQID);
264     DHLOGI("Do Disable distributed audio, devId: %{public}s, dhId: %{public}s, reqId:%{public}s.",
265         GetAnonyString(devId).c_str(), dhId.c_str(), reqId.c_str());
266     if (!CheckParams(devId, dhId)) {
267         DHLOGE("Disable params are incorrect.");
268         return ERR_DH_AUDIO_FAILED;
269     }
270     std::shared_ptr<DAudioSourceDev> sourceDev = nullptr;
271     {
272         std::lock_guard<std::mutex> lock(devMapMtx_);
273         auto device = audioDevMap_.find(devId);
274         if (device == audioDevMap_.end()) {
275             DHLOGE("Audio device not exist.");
276             return ERR_DH_AUDIO_SA_DEVICE_NOT_EXIST;
277         }
278         CHECK_NULL_RETURN(audioDevMap_[devId].dev, DH_SUCCESS);
279         audioDevMap_[devId].ports[dhId] = reqId;
280         sourceDev = audioDevMap_[devId].dev;
281     }
282     DHLOGD("Call source dev to disable daudio.");
283     int32_t result = sourceDev->DisableDAudio(dhId);
284     return OnDisableDAudio(devId, dhId, result);
285 }
286 
HandleDAudioNotify(const std::string & devId,const std::string & dhId,const int32_t eventType,const std::string & eventContent)287 int32_t DAudioSourceManager::HandleDAudioNotify(const std::string &devId, const std::string &dhId,
288     const int32_t eventType, const std::string &eventContent)
289 {
290     DHLOGD("Receive audio event from devId: %{public}s, event type: %{public}d. event content: %{public}s.",
291         GetAnonyString(devId).c_str(), eventType, eventContent.c_str());
292     if (eventContent.length() > DAUDIO_MAX_JSON_LEN || eventContent.empty()) {
293         return ERR_DH_AUDIO_FAILED;
294     }
295 
296     // now ctrl channel is also goto here, please sure here not crash.
297     cJSON *jParam = cJSON_Parse(eventContent.c_str());
298     if (CJsonParamCheck(jParam, { KEY_RANDOM_TASK_CODE })) {
299         DHLOGD("Receive audio notify from sink, random task code: %{public}s",
300             cJSON_GetObjectItemCaseSensitive(jParam, KEY_RANDOM_TASK_CODE)->valuestring);
301     }
302 
303     std::shared_ptr<DAudioSourceDev> sourceDev = nullptr;
304     {
305         std::lock_guard<std::mutex> lock(devMapMtx_);
306         auto device = audioDevMap_.find(devId);
307         if (device == audioDevMap_.end()) {
308             DHLOGE("Audio device not exist.");
309             cJSON_Delete(jParam);
310             return ERR_DH_AUDIO_SA_DEVICE_NOT_EXIST;
311         }
312         sourceDev = audioDevMap_[devId].dev;
313     }
314 
315     AudioEvent audioEvent(eventType, eventContent);
316     sourceDev->NotifyEvent(audioEvent);
317     cJSON_Delete(jParam);
318     return DH_SUCCESS;
319 }
320 
DAudioNotify(const std::string & devId,const std::string & dhId,const int32_t eventType,const std::string & eventContent)321 int32_t DAudioSourceManager::DAudioNotify(const std::string &devId, const std::string &dhId, const int32_t eventType,
322     const std::string &eventContent)
323 {
324     DHLOGD("Distributed audio notify, devId: %{public}s, dhId: %{public}s, eventType: %{public}d.",
325         GetAnonyString(devId).c_str(), dhId.c_str(), eventType);
326     {
327         std::lock_guard<std::mutex> lck(remoteSvrMutex_);
328         auto sinkProxy = sinkServiceMap_.find(devId);
329         if (sinkProxy != sinkServiceMap_.end()) {
330             if (sinkProxy->second != nullptr) {
331                 sinkProxy->second->DAudioNotify(localDevId_, dhId, eventType, eventContent);
332                 return DH_SUCCESS;
333             }
334         }
335     }
336 
337     auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
338     CHECK_NULL_RETURN(samgr, ERR_DH_AUDIO_NULLPTR);
339     auto remoteObject = samgr->GetSystemAbility(DISTRIBUTED_HARDWARE_AUDIO_SINK_SA_ID, devId);
340     CHECK_NULL_RETURN(remoteObject, ERR_DH_AUDIO_NULLPTR);
341     sptr<IDAudioSink> remoteSvrProxy = iface_cast<IDAudioSink>(remoteObject);
342     CHECK_NULL_RETURN(remoteSvrProxy, ERR_DH_AUDIO_NULLPTR);
343     {
344         std::lock_guard<std::mutex> lck(remoteSvrMutex_);
345         if (sinkServiceMap_.size() >= DAUDIO_SINK_SERVICE_MAX_SIZE) {
346             DHLOGE("Sink service map is full, not allow to insert anymore.");
347             return ERR_DH_AUDIO_FAILED;
348         }
349         sinkServiceMap_[devId] = remoteSvrProxy;
350         remoteSvrProxy->DAudioNotify(localDevId_, dhId, eventType, eventContent);
351     }
352     return DH_SUCCESS;
353 }
354 
OnEnableDAudio(const std::string & devId,const std::string & dhId,const int32_t result)355 int32_t DAudioSourceManager::OnEnableDAudio(const std::string &devId, const std::string &dhId, const int32_t result)
356 {
357     DHLOGI("On enable distributed audio devId: %{public}s, dhId: %{public}s, ret: %{public}d.",
358         GetAnonyString(devId).c_str(), dhId.c_str(), result);
359     std::string reqId = GetRequestId(devId, dhId);
360     if (reqId.empty()) {
361         return ERR_DH_AUDIO_FAILED;
362     }
363     if (result != DH_SUCCESS) {
364         DeleteAudioDevice(devId, dhId);
365     }
366 
367     CHECK_NULL_RETURN(ipcCallback_, ERR_DH_AUDIO_NULLPTR);
368     return ipcCallback_->OnNotifyRegResult(devId, dhId, reqId, result, "");
369 }
370 
OnHardwareStateChanged(const std::string & devId,const std::string & dhId,const int32_t state)371 int32_t DAudioSourceManager::OnHardwareStateChanged(const std::string &devId, const std::string &dhId,
372     const int32_t state)
373 {
374     DHLOGI("On distributed hardware state changed devId: %{public}s, dhId: %{public}s, ret: %{public}d.",
375         GetAnonyString(devId).c_str(), dhId.c_str(), state);
376 
377     CHECK_NULL_RETURN(ipcCallback_, ERR_DH_AUDIO_NULLPTR);
378     return ipcCallback_->OnHardwareStateChanged(devId, dhId, state);
379 }
380 
OnDataSyncTrigger(const std::string & devId)381 int32_t DAudioSourceManager::OnDataSyncTrigger(const std::string &devId)
382 {
383     DHLOGI("On data sync trigger devId: %{public}s.", GetAnonyString(devId).c_str());
384 
385     CHECK_NULL_RETURN(ipcCallback_, ERR_DH_AUDIO_NULLPTR);
386     return ipcCallback_->OnDataSyncTrigger(devId);
387 }
388 
OnDisableDAudio(const std::string & devId,const std::string & dhId,const int32_t result)389 int32_t DAudioSourceManager::OnDisableDAudio(const std::string &devId, const std::string &dhId, const int32_t result)
390 {
391     DHLOGI("On disable distributed audio devId: %{public}s, dhId: %{public}s, ret: %{public}d.",
392         GetAnonyString(devId).c_str(), dhId.c_str(), result);
393     std::string reqId = GetRequestId(devId, dhId);
394     if (reqId.empty()) {
395         return ERR_DH_AUDIO_FAILED;
396     }
397     if (result == DH_SUCCESS) {
398         DeleteAudioDevice(devId, dhId);
399     }
400 
401     CHECK_NULL_RETURN(ipcCallback_, ERR_DH_AUDIO_NULLPTR);
402     DaudioRadar::GetInstance().ReportDaudioUnInitProgress("OnDisableDAudio", AudioUnInit::DISABLED, result);
403     return ipcCallback_->OnNotifyUnregResult(devId, dhId, reqId, result, "");
404 }
405 
CreateAudioDevice(const std::string & devId)406 int32_t DAudioSourceManager::CreateAudioDevice(const std::string &devId)
407 {
408     DHLOGI("Create audio device.");
409     auto sourceDev = std::make_shared<DAudioSourceDev>(devId, daudioMgrCallback_);
410     if (sourceDev->AwakeAudioDev() != DH_SUCCESS) {
411         DHLOGE("Create new audio device failed.");
412         return ERR_DH_AUDIO_FAILED;
413     }
414     AudioDevice device = { devId, sourceDev };
415     audioDevMap_[devId] = device;
416     return DH_SUCCESS;
417 }
418 
DeleteAudioDevice(const std::string & devId,const std::string & dhId)419 void DAudioSourceManager::DeleteAudioDevice(const std::string &devId, const std::string &dhId)
420 {
421     DHLOGD("Delete audio device, devId = %{public}s, dhId = %{public}s.", GetAnonyString(devId).c_str(), dhId.c_str());
422     {
423         std::lock_guard<std::mutex> lock(devMapMtx_);
424         audioDevMap_[devId].ports.erase(dhId);
425         if (!audioDevMap_[devId].ports.empty()) {
426             DHLOGI("audioDevMap_[devId].ports is not empty");
427             return;
428         }
429     }
430     if (devClearThread_.joinable()) {
431         devClearThread_.join();
432     }
433     DHLOGD("audioDevMap_[devId].ports is empty");
434     devClearThread_ = std::thread([this, devId]() { this->ClearAudioDev(devId); });
435     if (pthread_setname_np(devClearThread_.native_handle(), DEVCLEAR_THREAD) != DH_SUCCESS) {
436         DHLOGE("Dev clear thread setname failed.");
437     }
438 }
439 
GetRequestId(const std::string & devId,const std::string & dhId)440 std::string DAudioSourceManager::GetRequestId(const std::string &devId, const std::string &dhId)
441 {
442     std::lock_guard<std::mutex> lock(devMapMtx_);
443     auto dev = audioDevMap_.find(devId);
444     if (dev == audioDevMap_.end()) {
445         DHLOGE("Audio device not exist.");
446         return "";
447     }
448     auto port = audioDevMap_[devId].ports.find(dhId);
449     if (port == audioDevMap_[devId].ports.end()) {
450         DHLOGE("Audio port not exist.");
451         return "";
452     }
453     return port->second;
454 }
455 
ClearAudioDev(const std::string & devId)456 void DAudioSourceManager::ClearAudioDev(const std::string &devId)
457 {
458     DHLOGI("ClearAudioDev, devId = %{public}s.", GetAnonyString(devId).c_str());
459     std::lock_guard<std::mutex> lock(devMapMtx_);
460     if (audioDevMap_[devId].ports.empty()) {
461         DHLOGI("audioDevMap_[devId].ports is empty.");
462         CHECK_NULL_VOID(audioDevMap_[devId].dev);
463         audioDevMap_[devId].dev->SleepAudioDev();
464         DHLOGI("back from SleepAudioDev.");
465         audioDevMap_.erase(devId);
466     }
467 }
468 
RestoreThreadStatus()469 void DAudioSourceManager::RestoreThreadStatus()
470 {
471     std::lock_guard<std::mutex> lock(devMapMtx_);
472     if (!audioDevMap_.empty()) {
473         for (auto &iter : audioDevMap_) {
474             CHECK_NULL_VOID(iter.second.dev);
475             iter.second.dev->SetThreadStatusFlag(true);
476         }
477     }
478 }
479 
ListenAudioDev()480 void DAudioSourceManager::ListenAudioDev()
481 {
482     auto taskFunc = [this]() {
483         std::lock_guard<std::mutex> lock(devMapMtx_);
484         for (auto &iter : audioDevMap_) {
485             CHECK_NULL_VOID(iter.second.dev);
486             if (iter.second.dev->GetThreadStatusFlag()) {
487                 iter.second.dev->SetThreadStatusFlag(false);
488             } else {
489                 DHLOGE("Exit the current process hicollie");
490                 _Exit(0);
491             }
492         }
493     };
494     OHOS::HiviewDFX::Watchdog::GetInstance().RunPeriodicalTask("SourceService", taskFunc,
495         WATCHDOG_INTERVAL_TIME, WATCHDOG_DELAY_TIME);
496 
497     while (isHicollieRunning_.load()) {
498         {
499             std::lock_guard<std::mutex> lock(devMapMtx_);
500             RestoreThreadStatus();
501         }
502         usleep(SLEEP_TIME);
503     }
504 }
505 
LoadAVSenderEngineProvider()506 int32_t DAudioSourceManager::LoadAVSenderEngineProvider()
507 {
508     DHLOGI("LoadAVSenderEngineProvider enter");
509     if (SENDER_SO_NAME.length() > PATH_MAX) {
510         DHLOGE("File open failed");
511         return ERR_DH_AUDIO_NULLPTR;
512     }
513     pSHandler_ = dlopen(SENDER_SO_NAME.c_str(), RTLD_LAZY | RTLD_NODELETE);
514     CHECK_NULL_RETURN(pSHandler_, ERR_DH_AUDIO_NULLPTR);
515     AVTransProviderClass getEngineFactoryFunc = (AVTransProviderClass)dlsym(pSHandler_,
516         GET_SENDER_PROVIDER_FUNC.c_str());
517     if (getEngineFactoryFunc == nullptr) {
518         DHLOGE("av transport engine factory function handler is null, failed reason : %{public}s", dlerror());
519         dlclose(pSHandler_);
520         pSHandler_ = nullptr;
521         return ERR_DH_AUDIO_NULLPTR;
522     }
523     sendProviderPtr_ = getEngineFactoryFunc(OWNER_NAME_D_SPEAKER);
524     DHLOGD("LoadAVSenderEngineProvider exit");
525     return DH_SUCCESS;
526 }
527 
UnloadAVSenderEngineProvider()528 int32_t DAudioSourceManager::UnloadAVSenderEngineProvider()
529 {
530     DHLOGI("UnloadAVSenderEngineProvider enter");
531     if (pSHandler_ != nullptr) {
532         dlclose(pSHandler_);
533         pSHandler_ = nullptr;
534     }
535     sendProviderPtr_ = nullptr;
536     return DH_SUCCESS;
537 }
538 
LoadAVReceiverEngineProvider()539 int32_t DAudioSourceManager::LoadAVReceiverEngineProvider()
540 {
541     DHLOGI("LoadAVReceiverEngineProvider enter");
542     if (RECEIVER_SO_NAME.length() > PATH_MAX) {
543         DHLOGE("File canonicalization failed");
544         return ERR_DH_AUDIO_NULLPTR;
545     }
546     pRHandler_ = dlopen(RECEIVER_SO_NAME.c_str(), RTLD_LAZY | RTLD_NODELETE);
547     CHECK_NULL_RETURN(pRHandler_, ERR_DH_AUDIO_NULLPTR);
548     AVTransProviderClass getEngineFactoryFunc = (AVTransProviderClass)dlsym(pRHandler_,
549         GET_RECEIVER_PROVIDER_FUNC.c_str());
550     if (getEngineFactoryFunc == nullptr) {
551         DHLOGE("av transport engine factory function handler is null, failed reason : %{public}s", dlerror());
552         dlclose(pRHandler_);
553         pRHandler_ = nullptr;
554         return ERR_DH_AUDIO_NULLPTR;
555     }
556     rcvProviderPtr_ = getEngineFactoryFunc(OWNER_NAME_D_MIC);
557     DHLOGD("LoadAVReceiverEngineProvider success");
558     return DH_SUCCESS;
559 }
560 
UnloadAVReceiverEngineProvider()561 int32_t DAudioSourceManager::UnloadAVReceiverEngineProvider()
562 {
563     DHLOGI("UnloadAVReceiverEngineProvider");
564     if (pRHandler_ != nullptr) {
565         dlclose(pRHandler_);
566         pRHandler_ = nullptr;
567     }
568     return DH_SUCCESS;
569 }
570 
getSenderProvider()571 IAVEngineProvider *DAudioSourceManager::getSenderProvider()
572 {
573     return sendProviderPtr_;
574 }
575 
getReceiverProvider()576 IAVEngineProvider *DAudioSourceManager::getReceiverProvider()
577 {
578     return rcvProviderPtr_;
579 }
580 
SourceManagerHandler(const std::shared_ptr<AppExecFwk::EventRunner> & runner)581 DAudioSourceManager::SourceManagerHandler::SourceManagerHandler(const std::shared_ptr<AppExecFwk::EventRunner>
582     &runner) : AppExecFwk::EventHandler(runner)
583 {
584     DHLOGD("Event handler is constructing.");
585     mapEventFuncs_[EVENT_MANAGER_ENABLE_DAUDIO] = &DAudioSourceManager::SourceManagerHandler::EnableDAudioCallback;
586     mapEventFuncs_[EVENT_MANAGER_DISABLE_DAUDIO] = &DAudioSourceManager::SourceManagerHandler::DisableDAudioCallback;
587 }
588 
~SourceManagerHandler()589 DAudioSourceManager::SourceManagerHandler::~SourceManagerHandler() {}
590 
ProcessEvent(const AppExecFwk::InnerEvent::Pointer & event)591 void DAudioSourceManager::SourceManagerHandler::ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event)
592 {
593     CHECK_NULL_VOID(event);
594     DHLOGI("Event Id=%{public}d.", event->GetInnerEventId());
595     switch (event->GetInnerEventId()) {
596         case EVENT_MANAGER_ENABLE_DAUDIO:
597             EnableDAudioCallback(event);
598             break;
599         case EVENT_MANAGER_DISABLE_DAUDIO:
600             DisableDAudioCallback(event);
601             break;
602         default:
603             DHLOGE("Event Id is invalid. %{public}d.", event->GetInnerEventId());
604             break;
605     }
606 }
607 
EnableDAudioCallback(const AppExecFwk::InnerEvent::Pointer & event)608 void DAudioSourceManager::SourceManagerHandler::EnableDAudioCallback(const AppExecFwk::InnerEvent::Pointer &event)
609 {
610     CHECK_NULL_VOID(event);
611     std::string eventParam;
612     if (GetEventParam(event, eventParam) != DH_SUCCESS) {
613         DHLOGE("Failed to get event parameters.");
614         return;
615     }
616     DAudioSourceManager::GetInstance().DoEnableDAudio(eventParam);
617 }
618 
DisableDAudioCallback(const AppExecFwk::InnerEvent::Pointer & event)619 void DAudioSourceManager::SourceManagerHandler::DisableDAudioCallback(const AppExecFwk::InnerEvent::Pointer &event)
620 {
621     CHECK_NULL_VOID(event);
622     std::string eventParam;
623     if (GetEventParam(event, eventParam) != DH_SUCCESS) {
624         DHLOGE("Failed to get event parameters.");
625         return;
626     }
627     DHLOGD("Disable audio device, param:%{public}s.", eventParam.c_str());
628     DAudioSourceManager::GetInstance().DoDisableDAudio(eventParam);
629 }
630 
GetEventParam(const AppExecFwk::InnerEvent::Pointer & event,std::string & eventParam)631 int32_t DAudioSourceManager::SourceManagerHandler::GetEventParam(const AppExecFwk::InnerEvent::Pointer &event,
632     std::string &eventParam)
633 {
634     CHECK_NULL_RETURN(event, ERR_DH_AUDIO_NULLPTR);
635     auto jsonString = event->GetSharedObject<std::string>().get();
636     CHECK_NULL_RETURN(jsonString, ERR_DH_AUDIO_NULLPTR);
637     eventParam = *jsonString;
638     return DH_SUCCESS;
639 }
640 } // DistributedHardware
641 } // OHOS
642