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
22 #include "daudio_constants.h"
23 #include "daudio_errorcode.h"
24 #include "daudio_log.h"
25 #include "daudio_util.h"
26
27 #undef DH_LOG_TAG
28 #define DH_LOG_TAG "DAudioSourceManager"
29
30 namespace OHOS {
31 namespace DistributedHardware {
32 namespace {
33 constexpr uint32_t MAX_DEVICE_ID_LENGTH = 200;
34 constexpr uint32_t MAX_DISTRIBUTED_HARDWARE_ID_LENGTH = 100;
35 }
36 IMPLEMENT_SINGLE_INSTANCE(DAudioSourceManager);
37 using AVTransProviderClass = IAVEngineProvider *(*)(const std::string &);
38
39 const std::string SENDER_SO_NAME = "libdistributed_av_sender.z.so";
40 const std::string GET_SENDER_PROVIDER_FUNC = "GetAVSenderEngineProvider";
41 const std::string RECEIVER_SO_NAME = "libdistributed_av_receiver.z.so";
42 const std::string GET_RECEIVER_PROVIDER_FUNC = "GetAVReceiverEngineProvider";
43 #ifdef __LP64__
44 const std::string LIB_LOAD_PATH = "/system/lib64/";
45 #else
46 const std::string LIB_LOAD_PATH = "/system/lib/";
47 #endif
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 DHLOGD("Distributed audio source manager destructed.");
60 }
61
Init(const sptr<IDAudioIpcCallback> & callback)62 int32_t DAudioSourceManager::Init(const sptr<IDAudioIpcCallback> &callback)
63 {
64 DHLOGI("Init audio source manager.");
65 if (callback == nullptr) {
66 DHLOGE("Callback is nullptr.");
67 return ERR_DH_AUDIO_NULLPTR;
68 }
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 ipcCallback_ = callback;
79 daudioMgrCallback_ = std::make_shared<DAudioSourceMgrCallback>();
80 int32_t ret = LoadAVSenderEngineProvider();
81 if (ret != DH_SUCCESS) {
82 DHLOGE("load av transport sender engine provider failed");
83 return ERR_DH_AUDIO_FAILED;
84 }
85 ret = LoadAVReceiverEngineProvider();
86 if (ret != DH_SUCCESS) {
87 DHLOGE("load av transport receiver engine provider failed.");
88 return ERR_DH_AUDIO_FAILED;
89 }
90 return DH_SUCCESS;
91 }
92
UnInit()93 int32_t DAudioSourceManager::UnInit()
94 {
95 DHLOGI("Uninit audio source manager.");
96 UnloadAVReceiverEngineProvider();
97 UnloadAVSenderEngineProvider();
98 {
99 std::lock_guard<std::mutex> lock(devMapMtx_);
100 for (auto iter = audioDevMap_.begin(); iter != audioDevMap_.end(); iter++) {
101 if (iter->second.dev == nullptr) {
102 continue;
103 }
104 iter->second.dev->SleepAudioDev();
105 }
106 audioDevMap_.clear();
107 }
108 if (devClearThread_.joinable()) {
109 devClearThread_.join();
110 }
111
112 ipcCallback_ = nullptr;
113 daudioMgrCallback_ = nullptr;
114 if (DAudioHdiHandler::GetInstance().UninitHdiHandler() != DH_SUCCESS) {
115 DHLOGE("Uninit Hdi handler failed.");
116 return ERR_DH_AUDIO_FAILED;
117 }
118 return DH_SUCCESS;
119 }
120
CheckParams(const std::string & devId,const std::string & dhId)121 static bool CheckParams(const std::string &devId, const std::string &dhId)
122 {
123 DHLOGD("Checking params of daudio.");
124 if (devId.empty() || dhId.empty() ||
125 devId.size() > MAX_DEVICE_ID_LENGTH || dhId.size() > MAX_DISTRIBUTED_HARDWARE_ID_LENGTH) {
126 return false;
127 }
128 return true;
129 }
130
EnableDAudio(const std::string & devId,const std::string & dhId,const std::string & version,const std::string & attrs,const std::string & reqId)131 int32_t DAudioSourceManager::EnableDAudio(const std::string &devId, const std::string &dhId,
132 const std::string &version, const std::string &attrs, const std::string &reqId)
133 {
134 DHLOGI("Enable distributed audio, devId: %s, dhId: %s, version: %s, reqId: %s.", GetAnonyString(devId).c_str(),
135 dhId.c_str(), version.c_str(), reqId.c_str());
136 if (!CheckParams(devId, dhId) || attrs.empty()) {
137 DHLOGE("Enable params are incorrect.");
138 return ERR_DH_AUDIO_FAILED;
139 }
140 std::lock_guard<std::mutex> lock(devMapMtx_);
141 auto dev = audioDevMap_.find(devId);
142 if (dev == audioDevMap_.end()) {
143 if (CreateAudioDevice(devId) != DH_SUCCESS) {
144 return ERR_DH_AUDIO_FAILED;
145 }
146 }
147 audioDevMap_[devId].ports[dhId] = reqId;
148 return audioDevMap_[devId].dev->EnableDAudio(dhId, attrs);
149 }
150
DisableDAudio(const std::string & devId,const std::string & dhId,const std::string & reqId)151 int32_t DAudioSourceManager::DisableDAudio(const std::string &devId, const std::string &dhId, const std::string &reqId)
152 {
153 DHLOGI("Disable distributed audio, devId: %s, dhId: %s, reqId: %s.", GetAnonyString(devId).c_str(), dhId.c_str(),
154 reqId.c_str());
155 if (!CheckParams(devId, dhId)) {
156 DHLOGE("Enable params are incorrect.");
157 return ERR_DH_AUDIO_FAILED;
158 }
159 std::lock_guard<std::mutex> lock(devMapMtx_);
160 auto dev = audioDevMap_.find(devId);
161 if (dev == audioDevMap_.end()) {
162 DHLOGE("Audio device not exist.");
163 return ERR_DH_AUDIO_SA_DEVICE_NOT_EXIST;
164 }
165 if (audioDevMap_[devId].dev == nullptr) {
166 DHLOGE("Audio device is null.");
167 return DH_SUCCESS;
168 }
169 audioDevMap_[devId].ports[dhId] = reqId;
170 return audioDevMap_[devId].dev->DisableDAudio(dhId);
171 }
172
HandleDAudioNotify(const std::string & devId,const std::string & dhId,const int32_t eventType,const std::string & eventContent)173 int32_t DAudioSourceManager::HandleDAudioNotify(const std::string &devId, const std::string &dhId,
174 const int32_t eventType, const std::string &eventContent)
175 {
176 DHLOGD("Receive audio event from devId: %s, event type: %d. event content: %s.",
177 GetAnonyString(devId).c_str(), eventType, eventContent.c_str());
178 if (eventContent.length() > DAUDIO_MAX_JSON_LEN || eventContent.empty()) {
179 return ERR_DH_AUDIO_FAILED;
180 }
181
182 // now ctrl channel is also goto here, please sure here not crash.
183 json jParam = json::parse(eventContent, nullptr, false);
184 if (JsonParamCheck(jParam, { KEY_RANDOM_TASK_CODE })) {
185 DHLOGD("Receive audio notify from sink, random task code: %s",
186 ((std::string)jParam[KEY_RANDOM_TASK_CODE]).c_str());
187 }
188
189 std::lock_guard<std::mutex> lock(devMapMtx_);
190 auto dev = audioDevMap_.find(devId);
191 if (dev == audioDevMap_.end()) {
192 DHLOGE("Audio device not exist.");
193 return ERR_DH_AUDIO_SA_DEVICE_NOT_EXIST;
194 }
195
196 AudioEvent audioEvent(eventType, eventContent);
197 audioDevMap_[devId].dev->NotifyEvent(audioEvent);
198 return DH_SUCCESS;
199 }
200
DAudioNotify(const std::string & devId,const std::string & dhId,const int32_t eventType,const std::string & eventContent)201 int32_t DAudioSourceManager::DAudioNotify(const std::string &devId, const std::string &dhId, const int32_t eventType,
202 const std::string &eventContent)
203 {
204 DHLOGD("Distributed audio notify, devId: %s, dhId: %s, eventType: %d.", GetAnonyString(devId).c_str(),
205 dhId.c_str(), eventType);
206 {
207 std::lock_guard<std::mutex> lck(remoteSvrMutex_);
208 auto sinkProxy = sinkServiceMap_.find(devId);
209 if (sinkProxy != sinkServiceMap_.end()) {
210 if (sinkProxy->second != nullptr) {
211 sinkProxy->second->DAudioNotify(localDevId_, dhId, eventType, eventContent);
212 return DH_SUCCESS;
213 }
214 }
215 }
216
217 auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
218 if (samgr == nullptr) {
219 DHLOGE("Failed to get system ability mgr.");
220 return ERR_DH_AUDIO_SA_GET_SAMGR_FAILED;
221 }
222 auto remoteObject = samgr->GetSystemAbility(DISTRIBUTED_HARDWARE_AUDIO_SINK_SA_ID, devId);
223 if (remoteObject == nullptr) {
224 DHLOGE("Object is null.");
225 return ERR_DH_AUDIO_SA_GET_REMOTE_SINK_FAILED;
226 }
227 sptr<IDAudioSink> remoteSvrProxy = iface_cast<IDAudioSink>(remoteObject);
228 if (remoteSvrProxy == nullptr) {
229 DHLOGE("Failed to get remote daudio sink SA.");
230 return ERR_DH_AUDIO_SA_GET_REMOTE_SINK_FAILED;
231 }
232 {
233 std::lock_guard<std::mutex> lck(remoteSvrMutex_);
234 sinkServiceMap_[devId] = remoteSvrProxy;
235 remoteSvrProxy->DAudioNotify(localDevId_, dhId, eventType, eventContent);
236 }
237 return DH_SUCCESS;
238 }
239
OnEnableDAudio(const std::string & devId,const std::string & dhId,const int32_t result)240 int32_t DAudioSourceManager::OnEnableDAudio(const std::string &devId, const std::string &dhId, const int32_t result)
241 {
242 DHLOGI("On enable distributed audio devId: %s, dhId: %s, ret: %d.", GetAnonyString(devId).c_str(), dhId.c_str(),
243 result);
244 std::string reqId = GetRequestId(devId, dhId);
245 if (reqId.empty()) {
246 return ERR_DH_AUDIO_FAILED;
247 }
248 if (result != DH_SUCCESS) {
249 DeleteAudioDevice(devId, dhId);
250 }
251
252 if (ipcCallback_ == nullptr) {
253 DHLOGE("Audio Ipc callback is null.");
254 return ERR_DH_AUDIO_NULLPTR;
255 }
256 return ipcCallback_->OnNotifyRegResult(devId, dhId, reqId, result, "");
257 }
258
OnDisableDAudio(const std::string & devId,const std::string & dhId,const int32_t result)259 int32_t DAudioSourceManager::OnDisableDAudio(const std::string &devId, const std::string &dhId, const int32_t result)
260 {
261 DHLOGI("On disable distributed audio devId: %s, dhId: %s, ret: %d.", GetAnonyString(devId).c_str(), dhId.c_str(),
262 result);
263 std::string reqId = GetRequestId(devId, dhId);
264 if (reqId.empty()) {
265 return ERR_DH_AUDIO_FAILED;
266 }
267 if (result == DH_SUCCESS) {
268 DeleteAudioDevice(devId, dhId);
269 }
270
271 if (ipcCallback_ == nullptr) {
272 DHLOGE("Audio Ipc callback is null.");
273 return ERR_DH_AUDIO_NULLPTR;
274 }
275 return ipcCallback_->OnNotifyUnregResult(devId, dhId, reqId, result, "");
276 }
277
CreateAudioDevice(const std::string & devId)278 int32_t DAudioSourceManager::CreateAudioDevice(const std::string &devId)
279 {
280 DHLOGI("Create audio device.");
281 auto sourceDev = std::make_shared<DAudioSourceDev>(devId, daudioMgrCallback_);
282 if (sourceDev->AwakeAudioDev() != DH_SUCCESS) {
283 DHLOGE("Create new audio device failed.");
284 return ERR_DH_AUDIO_FAILED;
285 }
286 AudioDevice device = { devId, sourceDev };
287 audioDevMap_[devId] = device;
288 return DH_SUCCESS;
289 }
290
DeleteAudioDevice(const std::string & devId,const std::string & dhId)291 void DAudioSourceManager::DeleteAudioDevice(const std::string &devId, const std::string &dhId)
292 {
293 DHLOGI("Delete audio device.");
294 std::lock_guard<std::mutex> lock(devMapMtx_);
295 audioDevMap_[devId].ports.erase(dhId);
296 if (!audioDevMap_[devId].ports.empty()) {
297 return;
298 }
299 if (devClearThread_.joinable()) {
300 devClearThread_.join();
301 }
302 devClearThread_ = std::thread(&DAudioSourceManager::ClearAudioDev, this, devId);
303 if (pthread_setname_np(devClearThread_.native_handle(), DEVCLEAR_THREAD) != DH_SUCCESS) {
304 DHLOGE("Dev clear thread setname failed.");
305 }
306 }
307
GetRequestId(const std::string & devId,const std::string & dhId)308 std::string DAudioSourceManager::GetRequestId(const std::string &devId, const std::string &dhId)
309 {
310 std::lock_guard<std::mutex> lock(devMapMtx_);
311 auto dev = audioDevMap_.find(devId);
312 if (dev == audioDevMap_.end()) {
313 DHLOGE("Audio device not exist.");
314 return "";
315 }
316 auto port = audioDevMap_[devId].ports.find(dhId);
317 if (port == audioDevMap_[devId].ports.end()) {
318 DHLOGE("Audio port not exist.");
319 return "";
320 }
321 return port->second;
322 }
323
ClearAudioDev(const std::string & devId)324 void DAudioSourceManager::ClearAudioDev(const std::string &devId)
325 {
326 std::lock_guard<std::mutex> lock(devMapMtx_);
327 if (audioDevMap_[devId].ports.empty()) {
328 audioDevMap_[devId].dev->SleepAudioDev();
329 audioDevMap_.erase(devId);
330 }
331 }
332
LoadAVSenderEngineProvider()333 int32_t DAudioSourceManager::LoadAVSenderEngineProvider()
334 {
335 DHLOGI("LoadAVSenderEngineProvider enter");
336 char path[PATH_MAX + 1] = {0x00};
337 if ((LIB_LOAD_PATH.length() + SENDER_SO_NAME.length()) > PATH_MAX ||
338 realpath((LIB_LOAD_PATH + SENDER_SO_NAME).c_str(), path) == nullptr) {
339 DHLOGE("File open failed");
340 return ERR_DH_AUDIO_TRANS_NULL_VALUE;
341 }
342 pSHandler_ = dlopen(path, RTLD_LAZY | RTLD_NODELETE);
343 if (pSHandler_ == nullptr) {
344 DHLOGE("%s handler load failed, failed reason : %s", path, dlerror());
345 return ERR_DH_AUDIO_TRANS_NULL_VALUE;
346 }
347 AVTransProviderClass getEngineFactoryFunc = (AVTransProviderClass)dlsym(pSHandler_,
348 GET_SENDER_PROVIDER_FUNC.c_str());
349 if (getEngineFactoryFunc == nullptr) {
350 DHLOGE("av transport engine factory function handler is null, failed reason : %s", dlerror());
351 dlclose(pSHandler_);
352 pSHandler_ = nullptr;
353 return ERR_DH_AUDIO_TRANS_NULL_VALUE;
354 }
355 sendProviderPtr_ = getEngineFactoryFunc(OWNER_NAME_D_SPEAKER);
356 DHLOGI("LoadAVSenderEngineProvider exit");
357 return DH_SUCCESS;
358 }
359
UnloadAVSenderEngineProvider()360 int32_t DAudioSourceManager::UnloadAVSenderEngineProvider()
361 {
362 DHLOGI("UnloadAVSenderEngineProvider enter");
363 if (pSHandler_ != nullptr) {
364 dlclose(pSHandler_);
365 pSHandler_ = nullptr;
366 }
367 sendProviderPtr_ = nullptr;
368 return DH_SUCCESS;
369 }
370
LoadAVReceiverEngineProvider()371 int32_t DAudioSourceManager::LoadAVReceiverEngineProvider()
372 {
373 DHLOGI("LoadAVReceiverEngineProvider enter");
374 char path[PATH_MAX + 1] = {0x00};
375 if ((LIB_LOAD_PATH.length() + RECEIVER_SO_NAME.length()) > PATH_MAX ||
376 realpath((LIB_LOAD_PATH + RECEIVER_SO_NAME).c_str(), path) == nullptr) {
377 DHLOGE("File canonicalization failed");
378 return ERR_DH_AUDIO_TRANS_NULL_VALUE;
379 }
380 pRHandler_ = dlopen(path, RTLD_LAZY | RTLD_NODELETE);
381 if (pRHandler_ == nullptr) {
382 DHLOGE("%s handler load failed, failed reason : %s", path, dlerror());
383 return ERR_DH_AUDIO_TRANS_NULL_VALUE;
384 }
385 AVTransProviderClass getEngineFactoryFunc = (AVTransProviderClass)dlsym(pRHandler_,
386 GET_RECEIVER_PROVIDER_FUNC.c_str());
387 if (getEngineFactoryFunc == nullptr) {
388 DHLOGE("av transport engine factory function handler is null, failed reason : %s", dlerror());
389 dlclose(pRHandler_);
390 pRHandler_ = nullptr;
391 return ERR_DH_AUDIO_TRANS_NULL_VALUE;
392 }
393 rcvProviderPtr_ = getEngineFactoryFunc(OWNER_NAME_D_MIC);
394 DHLOGE("LoadAVReceiverEngineProvider success");
395 return DH_SUCCESS;
396 }
397
UnloadAVReceiverEngineProvider()398 int32_t DAudioSourceManager::UnloadAVReceiverEngineProvider()
399 {
400 DHLOGI("UnloadAVReceiverEngineProvider");
401 if (pRHandler_ != nullptr) {
402 dlclose(pRHandler_);
403 pRHandler_ = nullptr;
404 }
405 return DH_SUCCESS;
406 }
407
getSenderProvider()408 IAVEngineProvider *DAudioSourceManager::getSenderProvider()
409 {
410 return sendProviderPtr_;
411 }
412
getReceiverProvider()413 IAVEngineProvider *DAudioSourceManager::getReceiverProvider()
414 {
415 return rcvProviderPtr_;
416 }
417 } // DistributedHardware
418 } // OHOS