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