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