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 "hdf_base.h"
20 #include "securec.h"
21 #include "intell_voice_log.h"
22 #include "scope_guard.h"
23 #include "intell_voice_engine_adapter_impl.h"
24
25 #undef HDF_LOG_TAG
26 #define HDF_LOG_TAG "IntelligentVoiceEngineManagerImpl"
27
28 namespace OHOS {
29 namespace IntelligentVoice {
30 namespace Engine {
IntellVoiceEngineManagerImplGetInstance(void)31 extern "C" IIntellVoiceEngineManager *IntellVoiceEngineManagerImplGetInstance(void)
32 {
33 return new (std::nothrow) IntellVoiceEngineManagerImpl();
34 }
35
LoadVendorLib()36 int32_t IntellVoiceEngineManagerImpl::LoadVendorLib()
37 {
38 std::string error;
39 const char *vendorLibPath = HDF_LIBRARY_FULL_PATH("libvendor_intell_voice_engine");
40 engineManagerPriv_.handle = dlopen(vendorLibPath, RTLD_LAZY);
41 if (engineManagerPriv_.handle == nullptr) {
42 error = dlerror();
43 INTELLIGENT_VOICE_LOGE("load path%{public}s, dlopen err=%{public}s", vendorLibPath, error.c_str());
44 return HDF_FAILURE;
45 }
46
47 (void)dlerror(); // clear existing error
48
49 engineManagerPriv_.getEngineManagerHalInst = reinterpret_cast<GetEngineManagerHalInstFunc>(dlsym(
50 engineManagerPriv_.handle, "GetIntellVoiceEngineManagerHalInst"));
51 if (engineManagerPriv_.getEngineManagerHalInst == nullptr) {
52 error = dlerror();
53 INTELLIGENT_VOICE_LOGE("dlsym GetIntellVoiceEngineManagerHalInst err=%{public}s", error.c_str());
54 dlclose(engineManagerPriv_.handle);
55 engineManagerPriv_.handle = nullptr;
56 return HDF_FAILURE;
57 }
58
59 INTELLIGENT_VOICE_LOGI("load vendor lib success");
60
61 return HDF_SUCCESS;
62 }
63
UnloadVendorLib()64 void IntellVoiceEngineManagerImpl::UnloadVendorLib()
65 {
66 engineManagerPriv_.handle = nullptr;
67 }
68
IntellVoiceEngineManagerImpl()69 IntellVoiceEngineManagerImpl::IntellVoiceEngineManagerImpl()
70 {
71 if (LoadVendorLib() == static_cast<int32_t>(HDF_SUCCESS)) {
72 inst_ = engineManagerPriv_.getEngineManagerHalInst();
73 }
74 }
75
~IntellVoiceEngineManagerImpl()76 IntellVoiceEngineManagerImpl::~IntellVoiceEngineManagerImpl()
77 {
78 adapters_.clear();
79 inst_ = nullptr;
80 UnloadVendorLib();
81 }
82
GetAdapterDescriptors(std::vector<IntellVoiceEngineAdapterDescriptor> & descs)83 int32_t IntellVoiceEngineManagerImpl::GetAdapterDescriptors(std::vector<IntellVoiceEngineAdapterDescriptor>& descs)
84 {
85 return HDF_SUCCESS;
86 }
87
CreateAdapter(const IntellVoiceEngineAdapterDescriptor & descriptor,sptr<IIntellVoiceEngineAdapter> & adapter)88 int32_t IntellVoiceEngineManagerImpl::CreateAdapter(
89 const IntellVoiceEngineAdapterDescriptor &descriptor, sptr<IIntellVoiceEngineAdapter> &adapter)
90 {
91 std::lock_guard<std::mutex> lock(mutex_);
92
93 if (inst_ == nullptr) {
94 INTELLIGENT_VOICE_LOGE("inst is nullptr");
95 return HDF_FAILURE;
96 }
97
98 std::unique_ptr<IEngine> engine = nullptr;
99 inst_->CreateAdapter(descriptor, engine);
100 if (engine == nullptr) {
101 INTELLIGENT_VOICE_LOGE("get adapter device from hal failed");
102 return HDF_FAILURE;
103 }
104
105 adapter = sptr<IIntellVoiceEngineAdapter>(new (std::nothrow) IntellVoiceEngineAdapterImpl(std::move(engine)));
106 if (adapter == nullptr) {
107 INTELLIGENT_VOICE_LOGE("malloc intell voice adapter server failed ");
108 return HDF_ERR_MALLOC_FAIL;
109 }
110
111 adapters_.insert(std::make_pair(descriptor.adapterType, adapter));
112 return HDF_SUCCESS;
113 }
114
ReleaseAdapter(const IntellVoiceEngineAdapterDescriptor & descriptor)115 int32_t IntellVoiceEngineManagerImpl::ReleaseAdapter(const IntellVoiceEngineAdapterDescriptor &descriptor)
116 {
117 std::lock_guard<std::mutex> lock(mutex_);
118
119 if (inst_ == nullptr) {
120 INTELLIGENT_VOICE_LOGE("inst is nullptr");
121 return HDF_FAILURE;
122 }
123
124 auto it = adapters_.find(descriptor.adapterType);
125 if (it == adapters_.end()) {
126 INTELLIGENT_VOICE_LOGW("can not find adapter, %{public}d", descriptor.adapterType);
127 return HDF_SUCCESS;
128 }
129
130 inst_->ReleaseAdapter(descriptor);
131
132 it->second = nullptr;
133 adapters_.erase(it);
134 return HDF_SUCCESS;
135 }
136
SetDataOprCallback(const sptr<IIntellVoiceDataOprCallback> & dataOprCallback)137 int32_t IntellVoiceEngineManagerImpl::SetDataOprCallback(const sptr<IIntellVoiceDataOprCallback>& dataOprCallback)
138 {
139 std::lock_guard<std::mutex> lock(mutex_);
140 INTELLIGENT_VOICE_LOGI("enter");
141
142 if (inst_ == nullptr) {
143 INTELLIGENT_VOICE_LOGE("inst is nullptr");
144 return HDF_FAILURE;
145 }
146
147 std::shared_ptr<DataOprListener> listener = std::make_shared<DataOprListener>(dataOprCallback);
148 if (listener == nullptr) {
149 INTELLIGENT_VOICE_LOGE("listener is nullptr");
150 return HDF_ERR_MALLOC_FAIL;
151 }
152
153 return inst_->SetDataOprListener(listener);
154 }
155
DataOprListener(sptr<IIntellVoiceDataOprCallback> cb)156 DataOprListener::DataOprListener(sptr<IIntellVoiceDataOprCallback> cb) : cb_(cb)
157 {
158 }
159
~DataOprListener()160 DataOprListener::~DataOprListener()
161 {
162 cb_ = nullptr;
163 }
164
OnDataOprEvent(IntellVoiceDataOprType type,const OprDataInfo & inData,OprDataInfo & outData)165 int32_t DataOprListener::OnDataOprEvent(IntellVoiceDataOprType type, const OprDataInfo &inData, OprDataInfo &outData)
166 {
167 if (cb_ == nullptr) {
168 INTELLIGENT_VOICE_LOGE("cb is nullptr");
169 return HDF_FAILURE;
170 }
171
172 sptr<Ashmem> inMem = nullptr;
173 if (type == OHOS::HDI::IntelligentVoice::Engine::V1_1::ENCRYPT_TYPE) {
174 inMem = CreateAshmemFromOprData(inData, "EnryptInIntellVoiceData");
175 } else if (type == OHOS::HDI::IntelligentVoice::Engine::V1_1::DECRYPT_TYPE) {
176 inMem = CreateAshmemFromOprData(inData, "DeryptInIntellVoiceData");
177 } else {
178 INTELLIGENT_VOICE_LOGE("invalid type:%{public}d", type);
179 return HDF_FAILURE;
180 }
181
182 if (inMem == nullptr) {
183 INTELLIGENT_VOICE_LOGE("failed to create ashmem");
184 return HDF_FAILURE;
185 }
186
187 sptr<Ashmem> outMem = nullptr;
188 ON_SCOPE_EXIT {
189 if (outMem != nullptr) {
190 INTELLIGENT_VOICE_LOGI("clear ashmem");
191 outMem->UnmapAshmem();
192 outMem->CloseAshmem();
193 }
194 };
195
196 int32_t ret = cb_->OnIntellVoiceDataOprEvent(type, inMem, outMem);
197 if (ret != HDF_SUCCESS) {
198 INTELLIGENT_VOICE_LOGE("data opr failed");
199 return HDF_FAILURE;
200 }
201
202 return FillOprDataFromAshmem(outMem, outData);
203 }
204
CreateAshmemFromOprData(const OprDataInfo & data,const std::string & name)205 sptr<Ashmem> DataOprListener::CreateAshmemFromOprData(const OprDataInfo &data, const std::string &name)
206 {
207 if ((data.data == nullptr) || (data.size == 0)) {
208 INTELLIGENT_VOICE_LOGE("data is empty");
209 return nullptr;
210 }
211
212 sptr<Ashmem> ashmem = OHOS::Ashmem::CreateAshmem(name.c_str(), data.size);
213 if (ashmem == nullptr) {
214 INTELLIGENT_VOICE_LOGE("failed to create ashmem");
215 return nullptr;
216 }
217
218 ON_SCOPE_EXIT {
219 ashmem->UnmapAshmem();
220 ashmem->CloseAshmem();
221 ashmem = nullptr;
222 };
223
224 if (!ashmem->MapReadAndWriteAshmem()) {
225 INTELLIGENT_VOICE_LOGE("failed to map ashmem");
226 return nullptr;
227 }
228
229 if (!ashmem->WriteToAshmem(data.data.get(), data.size, 0)) {
230 INTELLIGENT_VOICE_LOGE("failed to write ashmem");
231 return nullptr;
232 }
233
234 CANCEL_SCOPE_EXIT;
235 INTELLIGENT_VOICE_LOGI("create ashmem success, size:%{public}u", data.size);
236 return ashmem;
237 }
238
FillOprDataFromAshmem(const sptr<Ashmem> & ashmem,OprDataInfo & data)239 int32_t DataOprListener::FillOprDataFromAshmem(const sptr<Ashmem> &ashmem, OprDataInfo &data)
240 {
241 if (ashmem == nullptr) {
242 INTELLIGENT_VOICE_LOGE("ashmem is nullptr");
243 return HDF_FAILURE;
244 }
245
246 uint32_t size = static_cast<uint32_t>(ashmem->GetAshmemSize());
247 if (size == 0) {
248 INTELLIGENT_VOICE_LOGE("size is zero");
249 return HDF_FAILURE;
250 }
251
252 if (!ashmem->MapReadOnlyAshmem()) {
253 INTELLIGENT_VOICE_LOGE("map ashmem failed");
254 return HDF_FAILURE;
255 }
256
257 const uint8_t *mem = static_cast<const uint8_t *>(ashmem->ReadFromAshmem(size, 0));
258 if (mem == nullptr) {
259 INTELLIGENT_VOICE_LOGE("read from ashmem failed");
260 return HDF_FAILURE;
261 }
262
263 data.data = std::shared_ptr<char>(new char[size], [](char *p) { delete[] p; });
264 if (data.data == nullptr) {
265 INTELLIGENT_VOICE_LOGE("allocate data failed");
266 return HDF_FAILURE;
267 }
268
269 (void)memcpy_s(data.data.get(), size, mem, size);
270 data.size = size;
271 return HDF_SUCCESS;
272 }
273 }
274 }
275 }
276