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