• 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 
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