• 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_manager_napi.h"
16 #include "intell_voice_log.h"
17 #include "intell_voice_common_napi.h"
18 #include "intell_voice_napi_util.h"
19 #include "enroll_intell_voice_engine_napi.h"
20 #include "wakeup_intell_voice_engine_napi.h"
21 #include "wakeup_manager_napi.h"
22 #include "intell_voice_update_callback_napi.h"
23 #include "intell_voice_info.h"
24 
25 #define LOG_TAG "IntellVoiceManagerNapi"
26 
27 using namespace std;
28 using namespace OHOS::IntellVoice;
29 
30 namespace OHOS {
31 namespace IntellVoiceNapi {
32 static const std::string INTELLIGENT_VOICE_MANAGER_NAPI_CLASS_NAME = "IntelligentVoiceManager";
33 static const std::string SERVICE_CHANGE_CALLBACK_NAME = "serviceChange";
34 
35 static __thread napi_ref g_managerConstructor = nullptr;
36 napi_ref IntellVoiceManagerNapi::serviceChangeTypeRef_ = nullptr;
37 napi_ref IntellVoiceManagerNapi::engineTypeRef_ = nullptr;
38 napi_ref IntellVoiceManagerNapi::sensibilityTypeRef_ = nullptr;
39 napi_ref IntellVoiceManagerNapi::enrollEventTypeRef_ = nullptr;
40 napi_ref IntellVoiceManagerNapi::wakeupEventTypeRef_ = nullptr;
41 napi_ref IntellVoiceManagerNapi::errorCodeRef_ = nullptr;
42 napi_ref IntellVoiceManagerNapi::enrollResultRef_ = nullptr;
43 napi_ref IntellVoiceManagerNapi::uploadFileTypeRef_ = nullptr;
44 napi_ref IntellVoiceManagerNapi::evaluationResultCodeRef_ = nullptr;
45 
46 static const std::map<std::string, OHOS::IntellVoice::ServiceChangeType> SERVICE_CHANGE_TYPE_MAP = {
47     {"SERVICE_UNAVAILABLE", SERVICE_UNAVAILABLE},
48 };
49 
50 static const std::map<std::string, OHOS::IntellVoice::IntelligentVoiceEngineType> ENGINE_TYPE_MAP = {
51     {"ENROLL_ENGINE_TYPE", ENROLL_ENGINE_TYPE},
52     {"WAKEUP_ENGINE_TYPE", WAKEUP_ENGINE_TYPE},
53     {"UPDATE_ENGINE_TYPE", UPDATE_ENGINE_TYPE},
54 };
55 
56 static const std::map<std::string, OHOS::IntellVoice::SensibilityType> SENSIBILITY_TYPE_MAP = {
57     {"LOW_SENSIBILITY", LOW_SENSIBILITY},
58     {"MIDDLE_SENSIBILITY", MIDDLE_SENSIBILITY},
59     {"HIGH_SENSIBILITY", HIGH_SENSIBILITY},
60 };
61 
62 static const std::map<std::string, OHOS::IntellVoice::EnrollIntelligentVoiceEventType> ENROLL_EVENT_TYPE_MAP = {
63     {"INTELLIGENT_VOICE_EVENT_ENROLL_NONE", INTELLIGENT_VOICE_EVENT_ENROLL_NONE},
64     {"INTELLIGENT_VOICE_EVENT_ENROLL_INIT_DONE", INTELLIGENT_VOICE_EVENT_ENROLL_INIT_DONE},
65     {"INTELLIGENT_VOICE_EVENT_ENROLL_COMPLETE", INTELLIGENT_VOICE_EVENT_ENROLL_COMPLETE},
66     {"INTELLIGENT_VOICE_EVENT_COMMIT_ENROLL_COMPLETE", INTELLIGENT_VOICE_EVENT_COMMIT_ENROLL_COMPLETE},
67 };
68 
69 static const std::map<std::string, OHOS::IntellVoice::WakeupIntelligentVoiceEventType> WAKEUP_EVENT_TYPE_MAP = {
70     {"INTELLIGENT_VOICE_EVENT_WAKEUP_NONE", INTELLIGENT_VOICE_EVENT_WAKEUP_NONE},
71     {"INTELLIGENT_VOICE_EVENT_RECOGNIZE_COMPLETE", INTELLIGENT_VOICE_EVENT_RECOGNIZE_COMPLETE},
72     {"INTELLIGENT_VOICE_EVENT_HEADSET_RECOGNIZE_COMPLETE", INTELLIGENT_VOICE_EVENT_HEADSET_RECOGNIZE_COMPLETE},
73 };
74 
75 static const std::map<std::string, OHOS::IntellVoice::IntelligentVoiceErrorCode> ERROR_CODE_MAP = {
76     {"INTELLIGENT_VOICE_NO_MEMORY", INTELLIGENT_VOICE_NO_MEMORY},
77     {"INTELLIGENT_VOICE_INVALID_PARAM", INTELLIGENT_VOICE_INVALID_PARAM},
78     {"INTELLIGENT_VOICE_INIT_FAILED", INTELLIGENT_VOICE_INIT_FAILED},
79     {"INTELLIGENT_VOICE_COMMIT_ENROLL_FAILED", INTELLIGENT_VOICE_COMMIT_ENROLL_FAILED},
80     {"INTELLIGENT_VOICE_START_CAPTURER_FAILED", INTELLIGENT_VOICE_START_CAPTURER_FAILED},
81     {"INTELLIGENT_VOICE_READ_FAILED", INTELLIGENT_VOICE_READ_FAILED},
82     {"INTELLIGENT_VOICE_SYSTEM_ERROR", INTELLIGENT_VOICE_SYSTEM_ERROR},
83 };
84 
85 static const std::map<std::string, OHOS::IntellVoice::EnrollResult> ENROLL_RESULT_MAP = {
86     {"SUCCESS", OHOS::IntellVoice::EnrollResult::SUCCESS},
87     {"VPR_TRAIN_FAILED", OHOS::IntellVoice::EnrollResult::VPR_TRAIN_FAILED},
88     {"WAKEUP_PHRASE_NOT_MATCH", OHOS::IntellVoice::EnrollResult::WAKEUP_PHRASE_NOT_MATCH},
89     {"TOO_NOISY", OHOS::IntellVoice::EnrollResult::TOO_NOISY},
90     {"TOO_LOUD", OHOS::IntellVoice::EnrollResult::TOO_LOUD},
91     {"INTERVAL_LARGE", OHOS::IntellVoice::EnrollResult::INTERVAL_LARGE},
92     {"DIFFERENT_PERSON", OHOS::IntellVoice::EnrollResult::DIFFERENT_PERSON},
93     {"UNKNOWN_ERROR", OHOS::IntellVoice::EnrollResult::UNKNOWN_ERROR},
94 };
95 
96 static const std::map<std::string, OHOS::IntellVoice::UploadFileType> UPLOAD_FILE_TYPE_MAP = {
97     {"ENROLL_FILE", OHOS::IntellVoice::UploadFileType::ENROLL_FILE},
98     {"WAKEUP_FILE", OHOS::IntellVoice::UploadFileType::WAKEUP_FILE},
99 };
100 
101 static const std::map<std::string, OHOS::IntellVoice::EvaluationResultCode> EVALUATION_RESULT_CODE_MAP = {
102     {"UNKNOWN", OHOS::IntellVoice::UNKNOWN},
103     {"PASS", OHOS::IntellVoice::PASS},
104     {"WORD_EMPTY", OHOS::IntellVoice::WORD_EMPTY},
105     {"CHINESE_ONLY", OHOS::IntellVoice::CHINESE_ONLY},
106     {"INVALID_LENGTH", OHOS::IntellVoice::INVALID_LENGTH},
107     {"UNUSUAL_WORD", OHOS::IntellVoice::UNUSUAL_WORD},
108     {"CONSECUTIVE_SAME_WORD", OHOS::IntellVoice::CONSECUTIVE_SAME_WORD},
109     {"TOO_FEW_PHONEMES", OHOS::IntellVoice::TOO_FEW_PHONEMES},
110     {"TOO_MANY_PHONEMES", OHOS::IntellVoice::TOO_MANY_PHONEMES},
111     {"COMMON_INSTRUCTION", OHOS::IntellVoice::COMMON_INSTRUCTION},
112     {"COMMON_SPOKEN_LANGUAGE", OHOS::IntellVoice::COMMON_SPOKEN_LANGUAGE},
113     {"SENSITIVE_WORD", OHOS::IntellVoice::SENSITIVE_WORD},
114     {"NO_INITIAL_CONSONANT", OHOS::IntellVoice::NO_INITIAL_CONSONANT},
115     {"REPEATED_PHONEME", OHOS::IntellVoice::REPEATED_PHONEME},
116 };
117 
IntellVoiceManagerNapi()118 IntellVoiceManagerNapi::IntellVoiceManagerNapi()
119 {
120     INTELL_VOICE_LOG_INFO("enter");
121 }
122 
~IntellVoiceManagerNapi()123 IntellVoiceManagerNapi::~IntellVoiceManagerNapi()
124 {
125     INTELL_VOICE_LOG_INFO("enter");
126     if (wrapper_ != nullptr) {
127         napi_delete_reference(env_, wrapper_);
128     }
129 }
130 
Destruct(napi_env env,void * nativeObject,void * finalizeHint)131 void IntellVoiceManagerNapi::Destruct(napi_env env, void *nativeObject, void *finalizeHint)
132 {
133     INTELL_VOICE_LOG_INFO("enter");
134     if (nativeObject != nullptr) {
135         auto obj = static_cast<IntellVoiceManagerNapi *>(nativeObject);
136         delete obj;
137     }
138 }
139 
Construct(napi_env env,napi_callback_info info)140 napi_value IntellVoiceManagerNapi::Construct(napi_env env, napi_callback_info info)
141 {
142     INTELL_VOICE_LOG_INFO("enter");
143     napi_status status;
144     size_t argCount = 0;
145     napi_value jsThis = nullptr;
146     napi_value undefinedResult = nullptr;
147     napi_get_undefined(env, &undefinedResult);
148 
149     status = napi_get_cb_info(env, info, &argCount, nullptr, &jsThis, nullptr);
150     if (status != napi_ok) {
151         INTELL_VOICE_LOG_ERROR("invalid number of arguments");
152         return undefinedResult;
153     }
154 
155     unique_ptr<IntellVoiceManagerNapi> managerNapi = make_unique<IntellVoiceManagerNapi>();
156     if (managerNapi == nullptr) {
157         INTELL_VOICE_LOG_ERROR("no memory");
158         return undefinedResult;
159     }
160     managerNapi->env_ = env;
161     managerNapi->manager_ = IntellVoiceManager::GetInstance();
162     if (managerNapi->manager_ == nullptr) {
163         INTELL_VOICE_LOG_ERROR("create native manager failed");
164         return undefinedResult;
165     }
166 
167     status = napi_wrap(env,
168         jsThis,
169         static_cast<void *>(managerNapi.get()),
170         IntellVoiceManagerNapi::Destruct,
171         nullptr,
172         &(managerNapi->wrapper_));
173     if (status == napi_ok) {
174         managerNapi.release();
175         return jsThis;
176     }
177 
178     INTELL_VOICE_LOG_ERROR("failed to construct intell voice manager napi");
179     return undefinedResult;
180 }
181 
Export(napi_env env,napi_value exports)182 napi_value IntellVoiceManagerNapi::Export(napi_env env, napi_value exports)
183 {
184     napi_status status;
185     napi_value constructor;
186     napi_value result = nullptr;
187     const int32_t refCount = 1;
188     napi_get_undefined(env, &result);
189 
190     napi_property_descriptor properties[] = {
191         DECLARE_NAPI_FUNCTION("getCapabilityInfo", GetCapabilityInfo),
192         DECLARE_NAPI_FUNCTION("on", On),
193         DECLARE_NAPI_FUNCTION("off", Off),
194     };
195 
196     napi_property_descriptor staticProperties[] = {
197         DECLARE_NAPI_STATIC_FUNCTION("getIntelligentVoiceManager", GetIntelligentVoiceManager),
198         DECLARE_NAPI_PROPERTY("ServiceChangeType",
199             CreatePropertyBase(env, SERVICE_CHANGE_TYPE_MAP, serviceChangeTypeRef_)),
200         DECLARE_NAPI_PROPERTY("IntelligentVoiceEngineType", CreatePropertyBase(env, ENGINE_TYPE_MAP, engineTypeRef_)),
201         DECLARE_NAPI_PROPERTY("SensibilityType", CreatePropertyBase(env, SENSIBILITY_TYPE_MAP, sensibilityTypeRef_)),
202         DECLARE_NAPI_PROPERTY("EnrollIntelligentVoiceEventType",
203             CreatePropertyBase(env, ENROLL_EVENT_TYPE_MAP, enrollEventTypeRef_)),
204         DECLARE_NAPI_PROPERTY("WakeupIntelligentVoiceEventType",
205             CreatePropertyBase(env, WAKEUP_EVENT_TYPE_MAP, wakeupEventTypeRef_)),
206         DECLARE_NAPI_PROPERTY("IntelligentVoiceErrorCode", CreatePropertyBase(env, ERROR_CODE_MAP, errorCodeRef_)),
207         DECLARE_NAPI_PROPERTY("EnrollResult", CreatePropertyBase(env, ENROLL_RESULT_MAP, enrollResultRef_)),
208         DECLARE_NAPI_PROPERTY("UploadFileType", CreatePropertyBase(env, UPLOAD_FILE_TYPE_MAP, uploadFileTypeRef_)),
209         DECLARE_NAPI_PROPERTY("EvaluationResultCode",
210             CreatePropertyBase(env, EVALUATION_RESULT_CODE_MAP, evaluationResultCodeRef_)),
211     };
212 
213     status = napi_define_class(env, INTELLIGENT_VOICE_MANAGER_NAPI_CLASS_NAME.c_str(), NAPI_AUTO_LENGTH, Construct,
214         nullptr, sizeof(properties) / sizeof(properties[0]), properties, &constructor);
215     if (status != napi_ok) {
216         return result;
217     }
218 
219     status = napi_create_reference(env, constructor, refCount, &g_managerConstructor);
220     if (status == napi_ok) {
221         status = napi_set_named_property(env, exports, INTELLIGENT_VOICE_MANAGER_NAPI_CLASS_NAME.c_str(), constructor);
222         if (status == napi_ok) {
223             status = napi_define_properties(
224                 env, exports, sizeof(staticProperties) / sizeof(staticProperties[0]), staticProperties);
225             if (status == napi_ok) {
226                 return exports;
227             }
228         }
229     }
230 
231     INTELL_VOICE_LOG_ERROR("failed to export intelligent voice manager napi");
232     return result;
233 }
234 
GetCapabilityInfo(napi_env env,napi_callback_info info)235 napi_value IntellVoiceManagerNapi::GetCapabilityInfo(napi_env env, napi_callback_info info)
236 {
237     INTELL_VOICE_LOG_INFO("enter");
238     napi_value result = nullptr;
239     napi_create_array(env, &result);
240     napi_set_element(env, result, 0, SetValue(env, ENROLL_ENGINE_TYPE));
241     napi_set_element(env, result, 1, SetValue(env, WAKEUP_ENGINE_TYPE));
242     return result;
243 }
244 
On(napi_env env,napi_callback_info info)245 napi_value IntellVoiceManagerNapi::On(napi_env env, napi_callback_info info)
246 {
247     INTELL_VOICE_LOG_INFO("enter");
248 
249     napi_value undefinedResult = nullptr;
250     napi_get_undefined(env, &undefinedResult);
251 
252     const size_t expectArgCount = ARGC_TWO;
253     size_t argCount = ARGC_TWO;
254     napi_value args[expectArgCount] = { nullptr, nullptr };
255     napi_value jsThis = nullptr;
256 
257     napi_status status = napi_get_cb_info(env, info, &argCount, args, &jsThis, nullptr);
258     if (status != napi_ok || argCount != expectArgCount) {
259         INTELL_VOICE_LOG_ERROR("failed to get parameters");
260         return undefinedResult;
261     }
262 
263     napi_valuetype eventType = napi_undefined;
264     if (napi_typeof(env, args[0], &eventType) != napi_ok || eventType != napi_string) {
265         INTELL_VOICE_LOG_ERROR("callback event name type mismatch");
266         return undefinedResult;
267     }
268 
269     string callbackName = "";
270     status = GetValue(env, args[ARG_INDEX_0], callbackName);
271     if (status != napi_ok) {
272         INTELL_VOICE_LOG_ERROR("failed to get callbackName");
273         return undefinedResult;
274     }
275     INTELL_VOICE_LOG_INFO("callbackName: %{public}s", callbackName.c_str());
276     if (callbackName != SERVICE_CHANGE_CALLBACK_NAME) {
277         INTELL_VOICE_LOG_ERROR("No such off callback supported");
278         return undefinedResult;
279     }
280 
281     napi_valuetype handler = napi_undefined;
282     if (napi_typeof(env, args[ARG_INDEX_1], &handler) != napi_ok || handler != napi_function) {
283         INTELL_VOICE_LOG_ERROR("callback handler type mismatch");
284         return undefinedResult;
285     }
286 
287     return RegisterCallback(env, jsThis, args);
288 }
289 
RegisterCallback(napi_env env,napi_value jsThis,napi_value * args)290 napi_value IntellVoiceManagerNapi::RegisterCallback(napi_env env, napi_value jsThis, napi_value *args)
291 {
292     INTELL_VOICE_LOG_INFO("enter");
293     napi_value result = nullptr;
294     napi_get_undefined(env, &result);
295 
296     IntellVoiceManagerNapi *managerNapi = nullptr;
297     napi_status status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&managerNapi));
298     if (status != napi_ok || managerNapi == nullptr) {
299         INTELL_VOICE_LOG_ERROR("Failed to get engine napi instance");
300         return result;
301     }
302 
303     managerNapi->serviceChangeCb_ = new (std::nothrow) ServiceChangeCallbackNapi(env);
304     if (managerNapi->serviceChangeCb_ == nullptr) {
305         INTELL_VOICE_LOG_ERROR("allocate service change callback failed");
306         return result;
307     }
308 
309     managerNapi->serviceChangeCb_->SaveCallbackReference(args[ARG_INDEX_1]);
310     auto mgr = IntellVoiceManager::GetInstance();
311     if (mgr != nullptr) {
312         mgr->RegisterServiceDeathRecipient(managerNapi->serviceChangeCb_);
313     }
314 
315     return result;
316 }
317 
Off(napi_env env,napi_callback_info info)318 napi_value IntellVoiceManagerNapi::Off(napi_env env, napi_callback_info info)
319 {
320     INTELL_VOICE_LOG_INFO("enter");
321     napi_value undefinedResult = nullptr;
322     napi_get_undefined(env, &undefinedResult);
323 
324     const size_t expectArgCount = ARGC_TWO;
325     size_t argCount = ARGC_TWO;
326     napi_value args[expectArgCount] = {0};
327     napi_value jsThis = nullptr;
328 
329     napi_status status = napi_get_cb_info(env, info, &argCount, args, &jsThis, nullptr);
330     if (status != napi_ok || argCount < ARGC_ONE || argCount > ARGC_TWO) {
331         INTELL_VOICE_LOG_ERROR("failed to get parameters");
332         return undefinedResult;
333     }
334 
335     napi_valuetype eventType = napi_undefined;
336     if (napi_typeof(env, args[ARG_INDEX_0], &eventType) != napi_ok || eventType != napi_string) {
337         INTELL_VOICE_LOG_ERROR("callback event name type mismatch");
338         return undefinedResult;
339     }
340 
341     string callbackName = "";
342     status = GetValue(env, args[ARG_INDEX_0], callbackName);
343     if (status != napi_ok) {
344         INTELL_VOICE_LOG_ERROR("failed to get callbackName");
345         return undefinedResult;
346     }
347     INTELL_VOICE_LOG_INFO("callbackName: %{public}s", callbackName.c_str());
348     if (callbackName != SERVICE_CHANGE_CALLBACK_NAME) {
349         INTELL_VOICE_LOG_ERROR("No such off callback supported");
350         return undefinedResult;
351     }
352 
353     return DeregisterCallback(env, jsThis);
354 }
355 
DeregisterCallback(napi_env env,napi_value jsThis)356 napi_value IntellVoiceManagerNapi::DeregisterCallback(napi_env env, napi_value jsThis)
357 {
358     INTELL_VOICE_LOG_INFO("enter");
359     napi_value result = nullptr;
360     napi_get_undefined(env, &result);
361 
362     IntellVoiceManagerNapi *managerNapi = nullptr;
363     napi_status status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&managerNapi));
364     if (status != napi_ok || managerNapi == nullptr) {
365         INTELL_VOICE_LOG_ERROR("Failed to get engine napi instance");
366         return result;
367     }
368     if (managerNapi->serviceChangeCb_ == nullptr) {
369         INTELL_VOICE_LOG_ERROR("service change callback is nullptr");
370         return result;
371     }
372 
373     auto mgr = IntellVoiceManager::GetInstance();
374     if (mgr != nullptr) {
375         mgr->DeregisterServiceDeathRecipient(managerNapi->serviceChangeCb_);
376     }
377 
378     managerNapi->serviceChangeCb_ = nullptr;
379     return result;
380 }
381 
GetIntelligentVoiceManager(napi_env env,napi_callback_info info)382 napi_value IntellVoiceManagerNapi::GetIntelligentVoiceManager(napi_env env, napi_callback_info info)
383 {
384     INTELL_VOICE_LOG_INFO("enter");
385     if (!IntellVoiceCommonNapi::CheckIsSystemApp()) {
386         INTELL_VOICE_LOG_ERROR("Not system application!");
387         IntellVoiceCommonNapi::ThrowError(env, NAPI_INTELLIGENT_VOICE_NOT_SYSTEM_APPLICATION);
388         return nullptr;
389     }
390 
391     napi_status status;
392     size_t argCount = 0;
393 
394     status = napi_get_cb_info(env, info, &argCount, nullptr, nullptr, nullptr);
395     if (status != napi_ok || argCount != 0) {
396         INTELL_VOICE_LOG_ERROR("Invalid arguments");
397         IntellVoiceCommonNapi::ThrowError(env, NAPI_INTELLIGENT_VOICE_INVALID_PARAM);
398         return nullptr;
399     }
400 
401     return IntellVoiceManagerNapi::GetIntelligentVoiceManagerWrapper(env);
402 }
403 
GetIntelligentVoiceManagerWrapper(napi_env env)404 napi_value IntellVoiceManagerNapi::GetIntelligentVoiceManagerWrapper(napi_env env)
405 {
406     napi_status status;
407     napi_value result = nullptr;
408     napi_value constructor;
409 
410     status = napi_get_reference_value(env, g_managerConstructor, &constructor);
411     if (status == napi_ok) {
412         status = napi_new_instance(env, constructor, 0, nullptr, &result);
413         if (status == napi_ok) {
414             return result;
415         }
416     }
417 
418     INTELL_VOICE_LOG_ERROR("failed to get intell voice manager wrapper");
419     IntellVoiceCommonNapi::ThrowError(env, NAPI_INTELLIGENT_VOICE_NO_MEMORY);
420     napi_get_undefined(env, &result);
421 
422     return result;
423 }
424 
425 template <typename T>
CreatePropertyBase(napi_env env,T & propertyMap,napi_ref ref)426 napi_value IntellVoiceManagerNapi::CreatePropertyBase(napi_env env, T &propertyMap, napi_ref ref)
427 {
428     napi_value result = nullptr;
429     napi_status status;
430     napi_value enumNapiValue;
431 
432     status = napi_create_object(env, &result);
433     if (status != napi_ok) {
434         INTELL_VOICE_LOG_ERROR("failed to create object");
435         napi_get_undefined(env, &result);
436         return result;
437     }
438 
439     for (const auto &iter : propertyMap) {
440         std::string propName = iter.first;
441         int32_t enumValue = iter.second;
442 
443         enumNapiValue = SetValue(env, enumValue);
444         status = napi_set_named_property(env, result, propName.c_str(), enumNapiValue);
445         if (status != napi_ok) {
446             break;
447         }
448         propName.clear();
449     }
450 
451     if (status != napi_ok) {
452         INTELL_VOICE_LOG_ERROR("failed to set base property");
453         napi_get_undefined(env, &result);
454         return result;
455     }
456 
457     status = napi_create_reference(env, result, 1, &ref);
458     if (status != napi_ok) {
459         INTELL_VOICE_LOG_ERROR("failed to create base property");
460         napi_get_undefined(env, &result);
461         return result;
462     }
463 
464     INTELL_VOICE_LOG_INFO("create base property success");
465     return result;
466 }
467 
Export(napi_env env,napi_value exports)468 static napi_value Export(napi_env env, napi_value exports)
469 {
470     IntellVoiceManagerNapi::Export(env, exports);
471     WakeupManagerNapi::Export(env, exports);
472     EnrollIntellVoiceEngineNapi::Export(env, exports);
473     WakeupIntellVoiceEngineNapi::Export(env, exports);
474     return exports;
475 }
476 
477 static napi_module g_module = {
478     .nm_version = 1,
479     .nm_flags = 0,
480     .nm_filename = nullptr,
481     .nm_register_func = Export,
482     .nm_modname = "ai.intelligentVoice",
483     .nm_priv = ((void *)0),
484     .reserved = {0},
485 };
486 
RegisterModule(void)487 extern "C" __attribute__((constructor)) void RegisterModule(void)
488 {
489     napi_module_register(&g_module);
490 }
491 }  // namespace IntellVoiceNapi
492 }  // namespace OHOS
493