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