• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 #include "intell_voice_engine_manager_impl.h"
16 
17 #include <dlfcn.h>
18 #include <cinttypes>
19 #include "securec.h"
20 #include "hdf_base.h"
21 #include "securec.h"
22 #include "intell_voice_log.h"
23 #include "scope_guard.h"
24 #include "intell_voice_engine_adapter_impl.h"
25 
26 #undef HDF_LOG_TAG
27 #define HDF_LOG_TAG "IntelligentVoiceEngineManagerImpl"
28 
29 namespace OHOS {
30 namespace IntelligentVoice {
31 namespace Engine {
32 
33 #define CROSS_PROCESS_BUF_SIZE_LIMIT (256 *1024)
34 
IntellVoiceEngineManagerImplGetInstance(void)35 extern "C" IIntellVoiceEngineManager *IntellVoiceEngineManagerImplGetInstance(void)
36 {
37     return new (std::nothrow) IntellVoiceEngineManagerImpl();
38 }
39 
IntellVoiceEngineManagerImplRelease(IIntellVoiceEngineManager * mgr)40 extern "C" void IntellVoiceEngineManagerImplRelease(IIntellVoiceEngineManager *mgr)
41 {
42     INTELLIGENT_VOICE_LOGI("enter");
43     if (mgr == nullptr) {
44         INTELLIGENT_VOICE_LOGE("mgr is nullptr");
45         return;
46     }
47     delete mgr;
48 }
49 
LoadVendorLib()50 int32_t IntellVoiceEngineManagerImpl::LoadVendorLib()
51 {
52     std::string error;
53 #ifdef ONLY_SECOND_STAGE
54     const char *vendorLibPath = HDF_LIBRARY_FULL_PATH("libintell_voice_engine_wrapper");
55 #else
56     const char *vendorLibPath = HDF_LIBRARY_FULL_PATH("libvendor_intell_voice_engine");
57 #endif
58     engineManagerPriv_.handle = dlopen(vendorLibPath, RTLD_LAZY);
59     if (engineManagerPriv_.handle == nullptr) {
60         error = dlerror();
61         INTELLIGENT_VOICE_LOGE("load path%{public}s, dlopen err=%{public}s", vendorLibPath, error.c_str());
62         return HDF_FAILURE;
63     }
64 
65     (void)dlerror(); // clear existing error
66 
67     engineManagerPriv_.getEngineManagerHalInst = reinterpret_cast<GetEngineManagerHalInstFunc>(dlsym(
68         engineManagerPriv_.handle, "GetIntellVoiceEngineManagerHalInst"));
69     if (engineManagerPriv_.getEngineManagerHalInst == nullptr) {
70         error = dlerror();
71         INTELLIGENT_VOICE_LOGE("dlsym GetIntellVoiceEngineManagerHalInst err=%{public}s", error.c_str());
72         dlclose(engineManagerPriv_.handle);
73         engineManagerPriv_.handle = nullptr;
74         return HDF_FAILURE;
75     }
76 
77     INTELLIGENT_VOICE_LOGI("load vendor lib success");
78 
79     return HDF_SUCCESS;
80 }
81 
UnloadVendorLib()82 void IntellVoiceEngineManagerImpl::UnloadVendorLib()
83 {
84     engineManagerPriv_.handle = nullptr;
85 }
86 
IntellVoiceEngineManagerImpl()87 IntellVoiceEngineManagerImpl::IntellVoiceEngineManagerImpl()
88 {
89     if (LoadVendorLib() == static_cast<int32_t>(HDF_SUCCESS)) {
90         inst_ = engineManagerPriv_.getEngineManagerHalInst();
91     }
92 }
93 
~IntellVoiceEngineManagerImpl()94 IntellVoiceEngineManagerImpl::~IntellVoiceEngineManagerImpl()
95 {
96     adapters_.clear();
97     inst_ = nullptr;
98     UnloadVendorLib();
99 }
100 
GetAdapterDescriptors(std::vector<IntellVoiceEngineAdapterDescriptor> & descs)101 int32_t IntellVoiceEngineManagerImpl::GetAdapterDescriptors(std::vector<IntellVoiceEngineAdapterDescriptor>& descs)
102 {
103     return HDF_SUCCESS;
104 }
105 
CreateAdapter(const IntellVoiceEngineAdapterDescriptor & descriptor,sptr<HDI::IntelligentVoice::Engine::V1_0::IIntellVoiceEngineAdapter> & adapter)106 int32_t IntellVoiceEngineManagerImpl::CreateAdapter(const IntellVoiceEngineAdapterDescriptor &descriptor,
107     sptr<HDI::IntelligentVoice::Engine::V1_0::IIntellVoiceEngineAdapter> &adapter)
108 {
109     return CreateAdapterInner(descriptor, adapter);
110 }
111 
CreateAdapter_V_2(const IntellVoiceEngineAdapterDescriptor & descriptor,sptr<HDI::IntelligentVoice::Engine::V1_2::IIntellVoiceEngineAdapter> & adapter)112 int32_t IntellVoiceEngineManagerImpl::CreateAdapter_V_2(const IntellVoiceEngineAdapterDescriptor &descriptor,
113     sptr<HDI::IntelligentVoice::Engine::V1_2::IIntellVoiceEngineAdapter> &adapter)
114 {
115     return CreateAdapterInner(descriptor, adapter);
116 }
117 
118 template<typename T>
CreateAdapterInner(const IntellVoiceEngineAdapterDescriptor & descriptor,sptr<T> & adapter)119 int32_t IntellVoiceEngineManagerImpl::CreateAdapterInner(const IntellVoiceEngineAdapterDescriptor &descriptor,
120     sptr<T> &adapter)
121 {
122     std::lock_guard<std::mutex> lock(mutex_);
123 
124     if (inst_ == nullptr) {
125         INTELLIGENT_VOICE_LOGE("inst is nullptr");
126         return HDF_FAILURE;
127     }
128 
129     std::unique_ptr<IEngine> engine = nullptr;
130     inst_->CreateAdapter(descriptor, engine);
131     if (engine == nullptr) {
132         INTELLIGENT_VOICE_LOGE("get adapter device from hal failed");
133         return HDF_FAILURE;
134     }
135 
136     adapter = sptr<HDI::IntelligentVoice::Engine::V1_2::IIntellVoiceEngineAdapter>
137         (new (std::nothrow) IntellVoiceEngineAdapterImpl(std::move(engine)));
138     if (adapter == nullptr) {
139         INTELLIGENT_VOICE_LOGE("malloc intell voice adapter server failed ");
140         return HDF_ERR_MALLOC_FAIL;
141     }
142 
143     adapters_.insert(std::make_pair(descriptor.adapterType, adapter));
144     return HDF_SUCCESS;
145 }
146 
ReleaseAdapter(const IntellVoiceEngineAdapterDescriptor & descriptor)147 int32_t IntellVoiceEngineManagerImpl::ReleaseAdapter(const IntellVoiceEngineAdapterDescriptor &descriptor)
148 {
149     std::lock_guard<std::mutex> lock(mutex_);
150 
151     if (inst_ == nullptr) {
152         INTELLIGENT_VOICE_LOGE("inst is nullptr");
153         return HDF_FAILURE;
154     }
155 
156     auto it = adapters_.find(descriptor.adapterType);
157     if (it == adapters_.end()) {
158         INTELLIGENT_VOICE_LOGW("can not find adapter, %{public}d", descriptor.adapterType);
159         return HDF_SUCCESS;
160     }
161 
162     inst_->ReleaseAdapter(descriptor);
163 
164     it->second = nullptr;
165     adapters_.erase(it);
166     return HDF_SUCCESS;
167 }
168 
SetDataOprCallback(const sptr<IIntellVoiceDataOprCallback> & dataOprCallback)169 int32_t IntellVoiceEngineManagerImpl::SetDataOprCallback(const sptr<IIntellVoiceDataOprCallback> &dataOprCallback)
170 {
171     INTELLIGENT_VOICE_LOGI("enter");
172     if (inst_ == nullptr) {
173         INTELLIGENT_VOICE_LOGE("inst is nullptr");
174         return HDF_FAILURE;
175     }
176 
177     std::shared_ptr<DataOprListener> listener = std::make_shared<DataOprListener>(dataOprCallback);
178     if (listener == nullptr) {
179         INTELLIGENT_VOICE_LOGE("listener is nullptr");
180         return HDF_ERR_MALLOC_FAIL;
181     }
182 
183     return inst_->SetDataOprListener(listener);
184 }
185 
DataOprListener(sptr<IIntellVoiceDataOprCallback> cb)186 DataOprListener::DataOprListener(sptr<IIntellVoiceDataOprCallback> cb) : cb_(cb)
187 {
188 }
189 
~DataOprListener()190 DataOprListener::~DataOprListener()
191 {
192     cb_ = nullptr;
193 }
194 
OnDataOprEvent(IntellVoiceDataOprType type,const OprDataInfo & inData,OprDataInfo & outData)195 int32_t DataOprListener::OnDataOprEvent(IntellVoiceDataOprType type, const OprDataInfo &inData, OprDataInfo &outData)
196 {
197     if (cb_ == nullptr) {
198         INTELLIGENT_VOICE_LOGE("cb is nullptr");
199         return HDF_FAILURE;
200     }
201 
202     sptr<Ashmem> inMem = nullptr;
203     if (type == OHOS::HDI::IntelligentVoice::Engine::V1_1::ENCRYPT_TYPE) {
204         inMem = CreateAshmemFromOprData(inData, "EnryptInIntellVoiceData");
205     } else if (type == OHOS::HDI::IntelligentVoice::Engine::V1_1::DECRYPT_TYPE) {
206         inMem = CreateAshmemFromOprData(inData, "DeryptInIntellVoiceData");
207     } else {
208         INTELLIGENT_VOICE_LOGE("invalid type:%{public}d", type);
209         return HDF_FAILURE;
210     }
211 
212     if (inMem == nullptr) {
213         INTELLIGENT_VOICE_LOGE("failed to create ashmem");
214         return HDF_FAILURE;
215     }
216 
217     sptr<Ashmem> outMem = nullptr;
218     ON_SCOPE_EXIT {
219         if (outMem != nullptr) {
220             INTELLIGENT_VOICE_LOGI("clear ashmem");
221             outMem->UnmapAshmem();
222             outMem->CloseAshmem();
223         }
224     };
225 
226     int32_t ret = cb_->OnIntellVoiceDataOprEvent(type, inMem, outMem);
227     if (ret != HDF_SUCCESS) {
228         INTELLIGENT_VOICE_LOGE("data opr failed");
229         return HDF_FAILURE;
230     }
231 
232     return FillOprDataFromAshmem(outMem, outData);
233 }
234 
CreateAshmemFromOprData(const OprDataInfo & data,const std::string & name)235 sptr<Ashmem> DataOprListener::CreateAshmemFromOprData(const OprDataInfo &data, const std::string &name)
236 {
237     if ((data.data == nullptr) || (data.size == 0)) {
238         INTELLIGENT_VOICE_LOGE("data is empty");
239         return nullptr;
240     }
241 
242     sptr<Ashmem> ashmem = OHOS::Ashmem::CreateAshmem(name.c_str(), data.size);
243     if (ashmem == nullptr) {
244         INTELLIGENT_VOICE_LOGE("failed to create ashmem");
245         return nullptr;
246     }
247 
248     ON_SCOPE_EXIT {
249         ashmem->UnmapAshmem();
250         ashmem->CloseAshmem();
251         ashmem = nullptr;
252     };
253 
254     if (!ashmem->MapReadAndWriteAshmem()) {
255         INTELLIGENT_VOICE_LOGE("failed to map ashmem");
256         return nullptr;
257     }
258 
259     if (!ashmem->WriteToAshmem(data.data.get(), data.size, 0)) {
260         INTELLIGENT_VOICE_LOGE("failed to write ashmem");
261         return nullptr;
262     }
263 
264     CANCEL_SCOPE_EXIT;
265     INTELLIGENT_VOICE_LOGI("create ashmem success,  size:%{public}u", data.size);
266     return ashmem;
267 }
268 
FillOprDataFromAshmem(const sptr<Ashmem> & ashmem,OprDataInfo & data)269 int32_t DataOprListener::FillOprDataFromAshmem(const sptr<Ashmem> &ashmem, OprDataInfo &data)
270 {
271     if (ashmem == nullptr) {
272         INTELLIGENT_VOICE_LOGE("ashmem is nullptr");
273         return HDF_FAILURE;
274     }
275 
276     uint32_t size = static_cast<uint32_t>(ashmem->GetAshmemSize());
277     if (size == 0) {
278         INTELLIGENT_VOICE_LOGE("size is zero");
279         return HDF_FAILURE;
280     }
281 
282     if (!ashmem->MapReadOnlyAshmem()) {
283         INTELLIGENT_VOICE_LOGE("map ashmem failed");
284         return HDF_FAILURE;
285     }
286 
287     const uint8_t *mem = static_cast<const uint8_t *>(ashmem->ReadFromAshmem(size, 0));
288     if (mem == nullptr) {
289         INTELLIGENT_VOICE_LOGE("read from ashmem failed");
290         return HDF_FAILURE;
291     }
292 
293     data.data = std::shared_ptr<char>(new char[size], [](char *p) { delete[] p; });
294     if (data.data == nullptr) {
295         INTELLIGENT_VOICE_LOGE("allocate data failed");
296         return HDF_FAILURE;
297     }
298 
299     (void)memcpy_s(data.data.get(), size, mem, size);
300     data.size = size;
301     return HDF_SUCCESS;
302 }
303 
GetUploadFiles(int32_t numMax,std::vector<UploadHdiFile> & files)304 int32_t IntellVoiceEngineManagerImpl::GetUploadFiles(int32_t numMax, std::vector<UploadHdiFile> &files)
305 {
306     if (inst_ == nullptr) {
307         INTELLIGENT_VOICE_LOGE("inst is nullptr");
308         return HDF_FAILURE;
309     }
310 
311     if (inst_->GetUploadFiles(numMax, files) != 0) {
312         INTELLIGENT_VOICE_LOGE("getReportFile failed");
313         return HDF_FAILURE;
314     }
315     return HDF_SUCCESS;
316 }
317 
GetCloneFilesList(std::vector<std::string> & cloneFiles)318 int32_t IntellVoiceEngineManagerImpl::GetCloneFilesList(std::vector<std::string> &cloneFiles)
319 {
320     if (inst_ == nullptr) {
321         INTELLIGENT_VOICE_LOGE("inst is nullptr");
322         return HDF_FAILURE;
323     }
324 
325     return inst_->GetCloneFilesList(cloneFiles);
326 }
327 
GetCloneFile(const std::string & filePath,std::vector<uint8_t> & buffer)328 int32_t IntellVoiceEngineManagerImpl::GetCloneFile(const std::string &filePath, std::vector<uint8_t> &buffer)
329 {
330     if (inst_ == nullptr) {
331         INTELLIGENT_VOICE_LOGE("inst is nullptr");
332         return HDF_FAILURE;
333     }
334 
335     std::shared_ptr<uint8_t> data = nullptr;
336     uint32_t size = 0;
337 
338     int32_t ret = inst_->GetCloneFile(filePath, data, size);
339     if (ret != 0) {
340         INTELLIGENT_VOICE_LOGE("get clone file fail");
341         return ret;
342     }
343 
344     if (filePath.empty()) {
345         INTELLIGENT_VOICE_LOGE("file path is empty");
346         return HDF_FAILURE;
347     }
348 
349     if (data == nullptr) {
350         INTELLIGENT_VOICE_LOGE("data is nullptr");
351         return HDF_FAILURE;
352     }
353 
354     if (size == 0 || size > CROSS_PROCESS_BUF_SIZE_LIMIT) {
355         INTELLIGENT_VOICE_LOGE("size is invalid %{public}u", size);
356         return HDF_FAILURE;
357     }
358 
359     buffer.resize(size);
360     ret = memcpy_s(&buffer[0], size, data.get(), size);
361     if (ret != 0) {
362         INTELLIGENT_VOICE_LOGE("memcpy err");
363         return HDF_FAILURE;
364     }
365 
366     return 0;
367 }
368 
SendCloneFile(const std::string & filePath,const std::vector<uint8_t> & buffer)369 int32_t IntellVoiceEngineManagerImpl::SendCloneFile(const std::string &filePath, const std::vector<uint8_t> &buffer)
370 {
371     if (inst_ == nullptr) {
372         INTELLIGENT_VOICE_LOGE("inst is nullptr");
373         return HDF_FAILURE;
374     }
375 
376     if (filePath.empty()) {
377         INTELLIGENT_VOICE_LOGE("file path is empty");
378         return HDF_FAILURE;
379     }
380 
381     if (buffer.data() == nullptr) {
382         INTELLIGENT_VOICE_LOGE("data is nullptr");
383         return HDF_FAILURE;
384     }
385 
386     if (buffer.size() == 0 || buffer.size() > CROSS_PROCESS_BUF_SIZE_LIMIT) {
387         INTELLIGENT_VOICE_LOGE("size %{public}u is invalid", static_cast<uint32_t>(buffer.size()));
388         return HDF_FAILURE;
389     }
390 
391     return inst_->SendCloneFile(filePath, buffer.data(), buffer.size());
392 }
393 
ClearUserWakeupData(const std::string & wakeupPhrase)394 int32_t IntellVoiceEngineManagerImpl::ClearUserWakeupData(const std::string &wakeupPhrase)
395 {
396     if (inst_ == nullptr) {
397         INTELLIGENT_VOICE_LOGE("inst is nullptr, failed to clear user wakup data");
398         return HDF_FAILURE;
399     }
400 
401     return inst_->ClearUserWakeupData(wakeupPhrase);
402 }
403 }
404 }
405 }
406