• 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 "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