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