• 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_sink_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 "DAudioSinkManager"
29 
30 namespace OHOS {
31 namespace DistributedHardware {
32 static const std::string PARAM_CLOSE_SPEAKER = "{\"audioParam\":null,\"dhId\":\"" +
33     std::to_string(PIN_OUT_SPEAKER) + "\",\"eventType\":12}";
34 static const std::string PARAM_CLOSE_MIC = "{\"audioParam\":null,\"dhId\":\"" +
35     std::to_string(PIN_IN_MIC) + "\",\"eventType\":22}";
36 
37 IMPLEMENT_SINGLE_INSTANCE(DAudioSinkManager);
38 using AVTransProviderClass = IAVEngineProvider *(*)(const std::string &);
39 
40 const std::string SENDER_SO_NAME = "libdistributed_av_sender.z.so";
41 const std::string GET_SENDER_PROVIDER_FUNC = "GetAVSenderEngineProvider";
42 const std::string RECEIVER_SO_NAME = "libdistributed_av_receiver.z.so";
43 const std::string GET_RECEIVER_PROVIDER_FUNC = "GetAVReceiverEngineProvider";
44 #ifdef __LP64__
45 const std::string LIB_LOAD_PATH = "/system/lib64/";
46 #else
47 const std::string LIB_LOAD_PATH = "/system/lib/";
48 #endif
DAudioSinkManager()49 DAudioSinkManager::DAudioSinkManager()
50 {
51     DHLOGD("Distributed audio sink manager constructed.");
52 }
53 
~DAudioSinkManager()54 DAudioSinkManager::~DAudioSinkManager()
55 {
56     if (devClearThread_.joinable()) {
57         devClearThread_.join();
58     }
59     DHLOGD("Distributed audio sink manager deconstructed.");
60 }
61 
Init()62 int32_t DAudioSinkManager::Init()
63 {
64     DHLOGI("Init audio sink manager.");
65     int32_t ret = GetLocalDeviceNetworkId(localNetworkId_);
66     if (ret != DH_SUCCESS) {
67         DHLOGE("Get local network id failed, ret: %d.", ret);
68         return ret;
69     }
70 
71     ret = LoadAVReceiverEngineProvider();
72     if (ret != DH_SUCCESS || rcvProviderPtr_ == nullptr) {
73         DHLOGE("Load av transport receiver engine provider failed.");
74         return ERR_DH_AUDIO_FAILED;
75     }
76     providerListener_ = std::make_shared<EngineProviderListener>();
77     ret = rcvProviderPtr_->RegisterProviderCallback(providerListener_);
78     if (ret != DH_SUCCESS) {
79         DHLOGE("Register av transport receiver Provider Callback failed.");
80         return ERR_DH_AUDIO_FAILED;
81     }
82     DHLOGI("LoadAVReceiverEngineProvider success.");
83 
84     ret = LoadAVSenderEngineProvider();
85     if (ret != DH_SUCCESS || sendProviderPtr_ == nullptr) {
86         DHLOGI("Load av transport sender engine provider failed.");
87         return ERR_DH_AUDIO_FAILED;
88     }
89     ret = sendProviderPtr_->RegisterProviderCallback(providerListener_);
90     if (ret != DH_SUCCESS) {
91         DHLOGE("Register av transport sender Provider Callback failed.");
92         return ERR_DH_AUDIO_FAILED;
93     }
94     DHLOGI("LoadAVSenderEngineProvider success.");
95     return DH_SUCCESS;
96 }
97 
UnInit()98 int32_t DAudioSinkManager::UnInit()
99 {
100     DHLOGI("UnInit audio sink manager.");
101     UnloadAVSenderEngineProvider();
102     UnloadAVReceiverEngineProvider();
103     {
104         std::lock_guard<std::mutex> remoteSvrLock(remoteSvrMutex_);
105         sourceServiceMap_.clear();
106     }
107     {
108         std::lock_guard<std::mutex> devMapLock(devMapMutex_);
109         for (auto iter = audioDevMap_.begin(); iter != audioDevMap_.end(); iter++) {
110             if (iter->second != nullptr) {
111                 iter->second->SleepAudioDev();
112             }
113         }
114         audioDevMap_.clear();
115     }
116     if (devClearThread_.joinable()) {
117         devClearThread_.join();
118     }
119     return DH_SUCCESS;
120 }
121 
OnSinkDevReleased(const std::string & devId)122 void DAudioSinkManager::OnSinkDevReleased(const std::string &devId)
123 {
124     DHLOGI("Release audio device devId: %s.", GetAnonyString(devId).c_str());
125     if (devClearThread_.joinable()) {
126         devClearThread_.join();
127     }
128     devClearThread_ = std::thread(&DAudioSinkManager::ClearAudioDev, this, devId);
129     if (pthread_setname_np(devClearThread_.native_handle(), DEVCLEAR_THREAD) != DH_SUCCESS) {
130         DHLOGE("Dev clear thread setname failed.");
131     }
132 }
133 
HandleDAudioNotify(const std::string & devId,const std::string & dhId,const int32_t eventType,const std::string & eventContent)134 int32_t DAudioSinkManager::HandleDAudioNotify(const std::string &devId, const std::string &dhId,
135     const int32_t eventType, const std::string &eventContent)
136 {
137     DHLOGD("Receive audio event from devId: %s, event type: %d. event content: %s.",
138         GetAnonyString(devId).c_str(), eventType, eventContent.c_str());
139 
140     if (eventContent.length() > DAUDIO_MAX_JSON_LEN || eventContent.empty()
141         || !CheckDevIdIsLegal(devId) || eventType < 0 || eventType > MAX_EVENT_TYPE_NUM) {
142         return ERR_DH_AUDIO_FAILED;
143     }
144 
145     // now ctrl channel is also goto here, please sure here not crash.
146     json jParam = json::parse(eventContent, nullptr, false);
147     if (JsonParamCheck(jParam, { KEY_RANDOM_TASK_CODE })) {
148         DHLOGD("Receive audio notify from source, random task code: %s",
149             ((std::string)jParam[KEY_RANDOM_TASK_CODE]).c_str());
150     }
151     bool isDevExisted = false;
152     {
153         std::lock_guard<std::mutex> lock(devMapMutex_);
154         isDevExisted = audioDevMap_.find(devId) != audioDevMap_.end();
155     }
156     if (!isDevExisted && CreateAudioDevice(devId) != DH_SUCCESS) {
157         return ERR_DH_AUDIO_FAILED;
158     }
159     NotifyEvent(devId, eventType, eventContent);
160     return DH_SUCCESS;
161 }
162 
CreateAudioDevice(const std::string & devId)163 int32_t DAudioSinkManager::CreateAudioDevice(const std::string &devId)
164 {
165     DHLOGI("Create audio sink dev.");
166     std::shared_ptr<DAudioSinkDev> dev = nullptr;
167     {
168         std::lock_guard<std::mutex> lock(devMapMutex_);
169         if (audioDevMap_.find(devId) != audioDevMap_.end()) {
170             DHLOGI("Audio sink dev in map. devId: %s.", GetAnonyString(devId).c_str());
171             dev = audioDevMap_[devId];
172         } else {
173             dev = std::make_shared<DAudioSinkDev>(devId);
174             if (dev->AwakeAudioDev() != DH_SUCCESS) {
175                 DHLOGE("Awake audio dev failed.");
176                 return ERR_DH_AUDIO_FAILED;
177             }
178             audioDevMap_.emplace(devId, dev);
179         }
180     }
181 
182     int32_t ret = ERR_DH_AUDIO_FAILED;
183     if (channelState_ == ChannelState::SPK_CONTROL_OPENED) {
184         ret = dev->InitAVTransEngines(ChannelState::SPK_CONTROL_OPENED, rcvProviderPtr_);
185     }
186     if (channelState_ == ChannelState::MIC_CONTROL_OPENED) {
187         ret = dev->InitAVTransEngines(ChannelState::MIC_CONTROL_OPENED, sendProviderPtr_);
188     }
189     if (ret != DH_SUCCESS) {
190         DHLOGE("Init av transport sender engine failed.");
191         dev->SleepAudioDev();
192         {
193             std::lock_guard<std::mutex> lock(devMapMutex_);
194             audioDevMap_.erase(devId);
195         }
196         return ERR_DH_AUDIO_FAILED;
197     }
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 DAudioSinkManager::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.",
205         GetAnonyString(devId).c_str(), dhId.c_str(), eventType);
206 
207     {
208         std::lock_guard<std::mutex> lck(remoteSvrMutex_);
209         auto sinkProxy = sourceServiceMap_.find(devId);
210         if (sinkProxy != sourceServiceMap_.end()) {
211             if (sinkProxy->second != nullptr) {
212                 sinkProxy->second->DAudioNotify(localNetworkId_, dhId, eventType, eventContent);
213                 return DH_SUCCESS;
214             }
215         }
216     }
217 
218     auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
219     if (samgr == nullptr) {
220         DHLOGE("Failed to get system ability mgr.");
221         return ERR_DH_AUDIO_SA_GET_SAMGR_FAILED;
222     }
223     auto remoteObject = samgr->GetSystemAbility(DISTRIBUTED_HARDWARE_AUDIO_SOURCE_SA_ID, devId);
224     if (remoteObject == nullptr) {
225         DHLOGE("remoteObject is null.");
226         return ERR_DH_AUDIO_SA_GET_REMOTE_SINK_FAILED;
227     }
228     sptr<IDAudioSource> remoteSvrProxy = iface_cast<IDAudioSource>(remoteObject);
229     if (remoteSvrProxy == nullptr) {
230         DHLOGE("Failed to get remote daudio sink SA.");
231         return ERR_DH_AUDIO_SA_GET_REMOTE_SINK_FAILED;
232     }
233     {
234         std::lock_guard<std::mutex> lck(remoteSvrMutex_);
235         sourceServiceMap_[devId] = remoteSvrProxy;
236         remoteSvrProxy->DAudioNotify(localNetworkId_, dhId, eventType, eventContent);
237     }
238     return DH_SUCCESS;
239 }
240 
NotifyEvent(const std::string & devId,const int32_t eventType,const std::string & eventContent)241 void DAudioSinkManager::NotifyEvent(const std::string &devId, const int32_t eventType, const std::string &eventContent)
242 {
243     AudioEvent audioEvent(eventType, eventContent);
244     audioDevMap_[devId]->NotifyEvent(audioEvent);
245 }
246 
ClearAudioDev(const std::string & devId)247 void DAudioSinkManager::ClearAudioDev(const std::string &devId)
248 {
249     std::lock_guard<std::mutex> lock(devMapMutex_);
250     auto dev = audioDevMap_.find(devId);
251     if (dev == audioDevMap_.end()) {
252         DHLOGD("Device not register.");
253         return;
254     }
255     if (dev->second == nullptr) {
256         DHLOGD("Device already released.");
257         return;
258     }
259     dev->second->SleepAudioDev();
260     audioDevMap_.erase(devId);
261 }
262 
LoadAVReceiverEngineProvider()263 int32_t DAudioSinkManager::LoadAVReceiverEngineProvider()
264 {
265     DHLOGI("LoadAVReceiverEngineProvider enter");
266     char path[PATH_MAX + 1] = {0x00};
267     if ((LIB_LOAD_PATH.length() + RECEIVER_SO_NAME.length()) > PATH_MAX ||
268         realpath((LIB_LOAD_PATH + RECEIVER_SO_NAME).c_str(), path) == nullptr) {
269         DHLOGE("File open failed");
270         return ERR_DH_AUDIO_TRANS_NULL_VALUE;
271     }
272     pRHandler_ = dlopen(path, RTLD_LAZY | RTLD_NODELETE);
273     if (pRHandler_ == nullptr) {
274         DHLOGE("%s handler load failed, failed reason : %s", path, dlerror());
275         return ERR_DH_AUDIO_TRANS_NULL_VALUE;
276     }
277     AVTransProviderClass getEngineFactoryFunc = (AVTransProviderClass)dlsym(pRHandler_,
278         GET_RECEIVER_PROVIDER_FUNC.c_str());
279     if (getEngineFactoryFunc == nullptr) {
280         DHLOGE("av transport engine factory function handler is null, failed reason : %s", dlerror());
281         dlclose(pRHandler_);
282         pRHandler_ = nullptr;
283         return ERR_DH_AUDIO_TRANS_NULL_VALUE;
284     }
285     rcvProviderPtr_ = getEngineFactoryFunc(OWNER_NAME_D_SPEAKER);
286     DHLOGE("LoadAVReceiverEngineProvider success.");
287     return DH_SUCCESS;
288 }
289 
UnloadAVReceiverEngineProvider()290 int32_t DAudioSinkManager::UnloadAVReceiverEngineProvider()
291 {
292     DHLOGI("UnloadAVReceiverEngineProvider");
293     if (pRHandler_ != nullptr) {
294         dlclose(pRHandler_);
295         pRHandler_ = nullptr;
296     }
297     return DH_SUCCESS;
298 }
299 
LoadAVSenderEngineProvider()300 int32_t DAudioSinkManager::LoadAVSenderEngineProvider()
301 {
302     DHLOGI("LoadAVSenderEngineProvider enter");
303     char path[PATH_MAX + 1] = {0x00};
304     if ((LIB_LOAD_PATH.length() + SENDER_SO_NAME.length()) > PATH_MAX ||
305         realpath((LIB_LOAD_PATH + SENDER_SO_NAME).c_str(), path) == nullptr) {
306         DHLOGE("File open failed");
307         return ERR_DH_AUDIO_TRANS_NULL_VALUE;
308     }
309     pSHandler_ = dlopen(path, RTLD_LAZY | RTLD_NODELETE);
310     if (pSHandler_ == nullptr) {
311         DHLOGE("%s handler load failed, failed reason : %s", path, dlerror());
312         return ERR_DH_AUDIO_TRANS_NULL_VALUE;
313     }
314     AVTransProviderClass getEngineFactoryFunc = (AVTransProviderClass)dlsym(pSHandler_,
315         GET_SENDER_PROVIDER_FUNC.c_str());
316     if (getEngineFactoryFunc == nullptr) {
317         DHLOGE("av transport engine factory function handler is null, failed reason : %s", dlerror());
318         dlclose(pSHandler_);
319         pSHandler_ = nullptr;
320         return ERR_DH_AUDIO_TRANS_NULL_VALUE;
321     }
322     sendProviderPtr_ = getEngineFactoryFunc(OWNER_NAME_D_MIC);
323     return DH_SUCCESS;
324 }
325 
UnloadAVSenderEngineProvider()326 int32_t DAudioSinkManager::UnloadAVSenderEngineProvider()
327 {
328     DHLOGI("UnloadAVSenderEngineProvider enter");
329     if (pSHandler_ != nullptr) {
330         dlclose(pSHandler_);
331         pSHandler_ = nullptr;
332     }
333     return DH_SUCCESS;
334 }
335 
SetChannelState(const std::string & content)336 void DAudioSinkManager::SetChannelState(const std::string &content)
337 {
338     DHLOGI("The channel state belong to %s.", content.c_str());
339     if (content.find(OWNER_NAME_D_SPEAKER) != content.npos) {
340         channelState_ = ChannelState::SPK_CONTROL_OPENED;
341     } else if (content.find(OWNER_NAME_D_MIC) != content.npos) {
342         channelState_ = ChannelState::MIC_CONTROL_OPENED;
343     }
344 }
345 
OnProviderEvent(const AVTransEvent & event)346 int32_t EngineProviderListener::OnProviderEvent(const AVTransEvent &event)
347 {
348     DHLOGI("On provider event :%d", event.type);
349     if (event.type == EventType::EVENT_CHANNEL_OPENED) {
350         DHLOGI("Received control channel opened event, create audio device for peerDevId=%s, content=%s.",
351             GetAnonyString(event.peerDevId).c_str(), event.content.c_str());
352         DAudioSinkManager::GetInstance().SetChannelState(event.content);
353         DAudioSinkManager::GetInstance().CreateAudioDevice(event.peerDevId);
354     } else if (event.type == EventType::EVENT_CHANNEL_CLOSED) {
355         DHLOGI("Received control channel closed event, clear audio device for peerDevId=%s",
356             GetAnonyString(event.peerDevId).c_str());
357         if (event.content.find(OWNER_NAME_D_SPEAKER) != event.content.npos) {
358             DHLOGD("Notify audio event, event type: %d, event content: %s.", CLOSE_SPEAKER,
359                 PARAM_CLOSE_SPEAKER.c_str());
360             DAudioSinkManager::GetInstance().NotifyEvent(event.peerDevId, CLOSE_SPEAKER, PARAM_CLOSE_SPEAKER);
361         }
362         if (event.content.find(OWNER_NAME_D_MIC) != event.content.npos) {
363             DHLOGD("Notify audio event, event type: %d, event content: %s.", CLOSE_MIC, PARAM_CLOSE_MIC.c_str());
364             DAudioSinkManager::GetInstance().NotifyEvent(event.peerDevId, CLOSE_MIC, PARAM_CLOSE_MIC);
365         }
366     } else {
367         DHLOGE("Invaild event type.");
368     }
369     return DH_SUCCESS;
370 }
371 } // namespace DistributedHardware
372 } // namespace OHOS
373