• 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 "distributed_audio_client.h"
17 
18 #include <securec.h>
19 
20 #include <v1_0/audio_types.h>
21 
22 #include "audio_types.h"
23 #include "daudio_constants.h"
24 #include "daudio_errorcode.h"
25 #include "daudio_log.h"
26 
27 #undef DH_LOG_TAG
28 #define DH_LOG_TAG "DAudioAudioClient"
29 
30 namespace OHOS {
31 namespace DistributedHardware {
32 using OHOS::HDI::DistributedAudio::Audio::V1_0::IAudioAdapter;
33 using OHOS::HDI::DistributedAudio::Audio::V1_0::AudioAdapterDescriptor;
34 
InitDescriptorPort(const AudioAdapterDescriptor & desc,::AudioAdapterDescriptor & descInternal)35 static int32_t InitDescriptorPort(const AudioAdapterDescriptor &desc, ::AudioAdapterDescriptor &descInternal)
36 {
37     DHLOGI("Init audio adapter descriptor port.");
38     ::AudioPort *audioPorts = (::AudioPort *)malloc(desc.ports.size() * sizeof(AudioPort));
39     CHECK_NULL_RETURN(audioPorts, ERR_DH_AUDIO_NULLPTR);
40     descInternal.ports = audioPorts;
41 
42     bool isSuccess = true;
43     uint32_t cpyPortNum = 0;
44     constexpr uint32_t maxPortNameLen = 1000;
45     for (auto port : desc.ports) {
46         if (port.portName.length() >= maxPortNameLen) {
47             DHLOGE("Audio port name length is too long.");
48             continue;
49         }
50         char* portName = reinterpret_cast<char *>(calloc(port.portName.length() + STR_TERM_LEN, sizeof(char)));
51         if (portName == nullptr) {
52             DHLOGE("Calloc failed.");
53             isSuccess = false;
54             break;
55         }
56         if (strcpy_s(portName, port.portName.length() + STR_TERM_LEN, port.portName.c_str()) != EOK) {
57             DHLOGD("Strcpy_s port name failed.");
58             free(portName);
59             continue;
60         }
61         audioPorts->dir = static_cast<::AudioPortDirection>(port.dir);
62         audioPorts->portId = port.portId;
63         audioPorts->portName = portName;
64         audioPorts++;
65         cpyPortNum++;
66     }
67     if (isSuccess) {
68         return DH_SUCCESS;
69     }
70 
71     for (uint32_t i = 0; i < cpyPortNum; i++) {
72         if (descInternal.ports[i].portName != nullptr) {
73             free(const_cast<char *>(descInternal.ports[i].portName));
74         }
75     }
76     free(descInternal.ports);
77     descInternal.ports = nullptr;
78     return ERR_DH_AUDIO_HDI_CALL_FAILED;
79 }
80 
InitAudioAdapterDescriptor(AudioManagerContext * context,std::vector<AudioAdapterDescriptor> & descriptors)81 static int32_t InitAudioAdapterDescriptor(AudioManagerContext *context,
82     std::vector<AudioAdapterDescriptor> &descriptors)
83 {
84     DHLOGI("Init audio adapters descriptor, size is: %zu.", descriptors.size());
85     constexpr uint32_t maxAdapterNameLen = 1000;
86     constexpr uint32_t maxPortNum = 100;
87     constexpr uint32_t minPortNum = 1;
88     for (auto desc : descriptors) {
89         if (desc.ports.size() < minPortNum || desc.ports.size() > maxPortNum) {
90             DHLOGE("The descriptor ports size: %zu.", desc.ports.size());
91             continue;
92         }
93         if (desc.adapterName.length() >= maxAdapterNameLen) {
94             DHLOGE("Audio adapter name length is too long.");
95             continue;
96         }
97         char* adapterName = reinterpret_cast<char *>(calloc(desc.adapterName.length() + STR_TERM_LEN, sizeof(char)));
98         CHECK_NULL_RETURN(adapterName, ERR_DH_AUDIO_NULLPTR);
99         if (strcpy_s(adapterName, desc.adapterName.length() + STR_TERM_LEN, desc.adapterName.c_str()) != EOK) {
100             DHLOGD("Strcpy_s adapter name failed.");
101             free(adapterName);
102             continue;
103         }
104 
105         ::AudioAdapterDescriptor descInternal = {
106             .adapterName = adapterName,
107             .portNum = desc.ports.size(),
108         };
109         int32_t ret = InitDescriptorPort(desc, descInternal);
110         if (ret != DH_SUCCESS) {
111             DHLOGE("Init audio adapter descriptor port fail.");
112             free(adapterName);
113             descInternal.adapterName = nullptr;
114             return ret;
115         }
116         context->descriptors_.push_back(descInternal);
117     }
118     return DH_SUCCESS;
119 }
120 
GetAllAdaptersInternal(struct AudioManager * manager,struct::AudioAdapterDescriptor ** descs,int32_t * size)121 static int32_t GetAllAdaptersInternal(struct AudioManager *manager, struct ::AudioAdapterDescriptor **descs,
122     int32_t *size)
123 {
124     DHLOGI("Get all adapters.");
125     CHECK_NULL_RETURN(manager, ERR_DH_AUDIO_HDI_INVALID_PARAM);
126     CHECK_NULL_RETURN(descs, ERR_DH_AUDIO_HDI_INVALID_PARAM);
127     CHECK_NULL_RETURN(size, ERR_DH_AUDIO_HDI_INVALID_PARAM);
128     AudioManagerContext *context = reinterpret_cast<AudioManagerContext *>(manager);
129     CHECK_NULL_RETURN(context->proxy_, ERR_DH_AUDIO_NULLPTR);
130 
131     std::lock_guard<std::mutex> lock(context->mtx_);
132     std::vector<AudioAdapterDescriptor> descriptors;
133     int32_t ret = context->proxy_->GetAllAdapters(descriptors);
134     if (ret != DH_SUCCESS) {
135         *descs = nullptr;
136         *size = 0;
137         DHLOGE("Failed to get all adapters.");
138         return ret;
139     }
140     context->ClearDescriptors();
141     ret = InitAudioAdapterDescriptor(context, descriptors);
142     if (ret != DH_SUCCESS) {
143         return ret;
144     }
145     *descs = context->descriptors_.data();
146     *size = context->descriptors_.size();
147     return DH_SUCCESS;
148 }
149 
LoadAdapterInternal(struct AudioManager * manager,const struct::AudioAdapterDescriptor * desc,struct AudioAdapter ** adapter)150 static int32_t LoadAdapterInternal(struct AudioManager *manager, const struct ::AudioAdapterDescriptor *desc,
151     struct AudioAdapter **adapter)
152 {
153     DHLOGI("Load adapter.");
154     CHECK_NULL_RETURN(manager, ERR_DH_AUDIO_HDI_INVALID_PARAM);
155     CHECK_NULL_RETURN(desc, ERR_DH_AUDIO_HDI_INVALID_PARAM);
156     CHECK_NULL_RETURN(desc->adapterName, ERR_DH_AUDIO_HDI_INVALID_PARAM);
157     CHECK_NULL_RETURN(adapter, ERR_DH_AUDIO_HDI_INVALID_PARAM);
158     AudioManagerContext *context = reinterpret_cast<AudioManagerContext *>(manager);
159     std::string adpName = desc->adapterName;
160     {
161         std::lock_guard<std::mutex> lock(context->mtx_);
162         if (context->adapters_.find(adpName) != context->adapters_.end()) {
163             DHLOGD("Adapter already has been load.");
164             *adapter = &(context->adapters_[adpName]->instance_);
165             return DH_SUCCESS;
166         }
167     }
168 
169     AudioAdapterDescriptor descriptor = {
170         .adapterName = desc->adapterName,
171     };
172     sptr<IAudioAdapter> adapterProxy = nullptr;
173     CHECK_NULL_RETURN(context->proxy_, ERR_DH_AUDIO_NULLPTR);
174     int32_t ret = context->proxy_->LoadAdapter(descriptor, adapterProxy);
175     if (ret != DH_SUCCESS) {
176         DHLOGE("Failed to load the adapter.");
177         *adapter = nullptr;
178         return ret;
179     }
180 
181     auto adapterContext  = std::make_unique<AudioAdapterContext>();
182     adapterContext->proxy_ = adapterProxy;
183     *adapter = &adapterContext->instance_;
184     adapterContext->adapterName_ = descriptor.adapterName;
185     {
186         std::lock_guard<std::mutex> lock(context->mtx_);
187         context->adapters_.insert(std::make_pair(adpName, std::move(adapterContext)));
188     }
189     return DH_SUCCESS;
190 }
191 
UnloadAdapterInternal(struct AudioManager * manager,struct AudioAdapter * adapter)192 static void UnloadAdapterInternal(struct AudioManager *manager, struct AudioAdapter *adapter)
193 {
194     DHLOGI("Unload adapter.");
195     CHECK_NULL_VOID(manager);
196     CHECK_NULL_VOID(adapter);
197     AudioManagerContext *context = reinterpret_cast<AudioManagerContext *>(manager);
198     AudioAdapterContext *adapterContext = reinterpret_cast<AudioAdapterContext *>(adapter);
199     CHECK_NULL_VOID(context->proxy_);
200 
201     std::lock_guard<std::mutex> lock(context->mtx_);
202     for (auto it = context->adapters_.begin(); it != context->adapters_.end(); it++) {
203         if ((it->second).get() == adapterContext) {
204             int32_t ret = context->proxy_->UnloadAdapter(adapterContext->adapterName_);
205             if (ret != DH_SUCCESS) {
206                 DHLOGE("Failed to unload adapter.");
207                 return;
208             }
209             context->adapters_.erase(it);
210             break;
211         }
212     }
213     DHLOGI("Unload adapter success.");
214 }
215 
ClearDescriptors()216 void AudioManagerContext::ClearDescriptors()
217 {
218     DHLOGI("Clear descriptors enter.");
219     for (auto &desc : descriptors_) {
220         if (desc.adapterName != nullptr) {
221             free(const_cast<char *>(desc.adapterName));
222         }
223         for (uint32_t i = 0; i < desc.portNum; i++) {
224             if (desc.ports[i].portName != nullptr) {
225                 free(const_cast<char *>(desc.ports[i].portName));
226             }
227         }
228         free(desc.ports);
229     }
230     descriptors_.clear();
231     DHLOGI("Clear descriptors end.");
232 }
233 
AudioManagerContext()234 AudioManagerContext::AudioManagerContext()
235 {
236     instance_.GetAllAdapters = GetAllAdaptersInternal;
237     instance_.LoadAdapter = LoadAdapterInternal;
238     instance_.UnloadAdapter = UnloadAdapterInternal;
239 
240     instance_.ReleaseAudioManagerObject = nullptr;
241 }
242 
~AudioManagerContext()243 AudioManagerContext::~AudioManagerContext()
244 {
245     adapters_.clear();
246     ClearDescriptors();
247 }
248 
249 AudioManagerContext g_AudioManagerContext;
250 
AudioManagerInit()251 static bool AudioManagerInit()
252 {
253     std::lock_guard<std::mutex> lock(g_AudioManagerContext.mtx_);
254 
255     g_AudioManagerContext.adapters_.clear();
256     g_AudioManagerContext.ClearDescriptors();
257 
258     sptr<IAudioManager> audioMgr = IAudioManager::Get("daudio_primary_service", false);
259     CHECK_NULL_RETURN(audioMgr, false);
260     g_AudioManagerContext.proxy_ = audioMgr;
261     return true;
262 }
263 } // DistributedHardware
264 } // OHOS
265 
266 #ifdef __cplusplus
267 extern "C" {
268 #endif
269 
GetAudioManagerFuncs(void)270 struct AudioManager *GetAudioManagerFuncs(void)
271 {
272     if (OHOS::DistributedHardware::AudioManagerInit()) {
273         return &OHOS::DistributedHardware::g_AudioManagerContext.instance_;
274     } else {
275         return nullptr;
276     }
277 }
278 
279 #ifdef __cplusplus
280 }
281 #endif
282