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
16 #include "enroll_intell_voice_engine_napi.h"
17
18 #include "iservice_registry.h"
19 #include "system_ability_definition.h"
20
21 #include "intell_voice_common_napi.h"
22 #include "intell_voice_napi_util.h"
23 #include "intell_voice_napi_queue.h"
24 #include "intell_voice_log.h"
25 #include "i_intell_voice_engine_callback.h"
26
27 #define LOG_TAG "EnrollEngineNapi"
28
29 using namespace OHOS::IntellVoice;
30 using namespace OHOS::IntellVoiceEngine;
31 using namespace std;
32
33 namespace OHOS {
34 namespace IntellVoiceNapi {
35 class EvaluateContext : public AsyncContext {
36 public:
EvaluateContext(napi_env env)37 explicit EvaluateContext(napi_env env) : AsyncContext(env) {};
38 string word;
39 EvaluationResult info;
40 };
41
42 static __thread napi_ref g_enrollEngineConstructor = nullptr;
43 EnrollIntelligentVoiceEngineDescriptor EnrollIntellVoiceEngineNapi::g_enrollEngineDesc_;
44 int32_t EnrollIntellVoiceEngineNapi::constructResult_ = NAPI_INTELLIGENT_VOICE_SUCCESS;
45
46 static const std::string ENROLL_ENGINE_NAPI_CLASS_NAME = "EnrollIntelligentVoiceEngine";
47
EnrollIntellVoiceEngineNapi()48 EnrollIntellVoiceEngineNapi::EnrollIntellVoiceEngineNapi()
49 {
50 INTELL_VOICE_LOG_INFO("enter");
51 }
52
~EnrollIntellVoiceEngineNapi()53 EnrollIntellVoiceEngineNapi::~EnrollIntellVoiceEngineNapi()
54 {
55 INTELL_VOICE_LOG_INFO("enter");
56 if (wrapper_ != nullptr) {
57 napi_delete_reference(env_, wrapper_);
58 }
59 }
60
Export(napi_env env,napi_value exports)61 napi_value EnrollIntellVoiceEngineNapi::Export(napi_env env, napi_value exports)
62 {
63 napi_status status;
64 napi_value constructor;
65 napi_value result = nullptr;
66 const int32_t refCount = 1;
67 napi_get_undefined(env, &result);
68
69 napi_property_descriptor properties[] = {
70 DECLARE_NAPI_FUNCTION("getSupportedRegions", GetSupportedRegions),
71 DECLARE_NAPI_FUNCTION("init", Init),
72 DECLARE_NAPI_FUNCTION("enrollForResult", EnrollForResult),
73 DECLARE_NAPI_FUNCTION("stop", Stop),
74 DECLARE_NAPI_FUNCTION("setSensibility", SetSensibility),
75 DECLARE_NAPI_FUNCTION("setWakeupHapInfo", SetWakeupHapInfo),
76 DECLARE_NAPI_FUNCTION("setParameter", SetParameter),
77 DECLARE_NAPI_FUNCTION("getParameter", GetParameter),
78 DECLARE_NAPI_FUNCTION("evaluateForResult", EvaluateForResult),
79 DECLARE_NAPI_FUNCTION("release", Release),
80 DECLARE_NAPI_FUNCTION("commit", Commit),
81 };
82
83 napi_property_descriptor static_prop[] = {
84 DECLARE_NAPI_STATIC_FUNCTION(
85 "createEnrollIntelligentVoiceEngine", CreateEnrollIntelligentVoiceEngine)
86 };
87
88 status = napi_define_class(env,
89 ENROLL_ENGINE_NAPI_CLASS_NAME.c_str(),
90 NAPI_AUTO_LENGTH,
91 Construct,
92 nullptr,
93 sizeof(properties) / sizeof(properties[0]),
94 properties,
95 &constructor);
96 if (status != napi_ok) {
97 return result;
98 }
99
100 status = napi_create_reference(env, constructor, refCount, &g_enrollEngineConstructor);
101 if (status == napi_ok) {
102 status = napi_set_named_property(env, exports, ENROLL_ENGINE_NAPI_CLASS_NAME.c_str(), constructor);
103 if (status == napi_ok) {
104 status = napi_define_properties(env, exports,
105 sizeof(static_prop) / sizeof(static_prop[0]), static_prop);
106 if (status == napi_ok) {
107 return exports;
108 }
109 }
110 }
111
112 return result;
113 }
114
Destruct(napi_env env,void * nativeObject,void * finalizeHint)115 void EnrollIntellVoiceEngineNapi::Destruct(napi_env env, void *nativeObject, void *finalizeHint)
116 {
117 if (nativeObject != nullptr) {
118 auto obj = static_cast<EnrollIntellVoiceEngineNapi *>(nativeObject);
119 delete obj;
120 }
121 }
122
Construct(napi_env env,napi_callback_info info)123 napi_value EnrollIntellVoiceEngineNapi::Construct(napi_env env, napi_callback_info info)
124 {
125 INTELL_VOICE_LOG_INFO("enter");
126 napi_status status;
127 size_t argc = ARGC_ONE;
128 napi_value args[ARGC_ONE] = { nullptr };
129 napi_value jsThis = nullptr;
130 napi_value undefinedResult = nullptr;
131 napi_get_undefined(env, &undefinedResult);
132
133 constructResult_ = NAPI_INTELLIGENT_VOICE_SUCCESS;
134 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &jsThis, nullptr));
135
136 unique_ptr<EnrollIntellVoiceEngineNapi> engineNapi = make_unique<EnrollIntellVoiceEngineNapi>();
137 if (engineNapi == nullptr) {
138 INTELL_VOICE_LOG_ERROR("Failed to create EnrollIntellVoiceEngineNapi, No memory");
139 constructResult_ = NAPI_INTELLIGENT_VOICE_NO_MEMORY;
140 return undefinedResult;
141 }
142
143 engineNapi->env_ = env;
144 engineNapi->engine_ = std::make_shared<EnrollIntellVoiceEngine>(g_enrollEngineDesc_);
145 if (engineNapi->engine_ == nullptr) {
146 INTELL_VOICE_LOG_ERROR("create intell voice engine failed");
147 constructResult_ = NAPI_INTELLIGENT_VOICE_NO_MEMORY;
148 return undefinedResult;
149 }
150
151 constructResult_ = IntellVoiceCommonNapi::ConvertResultCode(engineNapi->engine_->result_);
152 if (constructResult_ != NAPI_INTELLIGENT_VOICE_SUCCESS) {
153 return undefinedResult;
154 }
155
156 engineNapi->callbackNapi_ = std::make_shared<EnrollIntellVoiceEngineCallbackNapi>(env);
157 if (engineNapi->callbackNapi_ == nullptr) {
158 INTELL_VOICE_LOG_ERROR("create intell voice engine callback napi failed");
159 constructResult_ = NAPI_INTELLIGENT_VOICE_NO_MEMORY;
160 return undefinedResult;
161 }
162
163 if (engineNapi->engine_->SetCallback(engineNapi->callbackNapi_) != 0) {
164 INTELL_VOICE_LOG_ERROR("set callback failed");
165 constructResult_ = NAPI_INTELLIGENT_VOICE_SYSTEM_ERROR;
166 return undefinedResult;
167 }
168
169 status = napi_wrap(env, jsThis, static_cast<void *>(engineNapi.get()),
170 EnrollIntellVoiceEngineNapi::Destruct, nullptr, &(engineNapi->wrapper_));
171 if (status == napi_ok) {
172 engineNapi.release();
173 return jsThis;
174 }
175
176 INTELL_VOICE_LOG_ERROR("wrap enroll intell voice engine failed");
177 return undefinedResult;
178 }
179
CreateEnrollIntelligentVoiceEngine(napi_env env,napi_callback_info info)180 napi_value EnrollIntellVoiceEngineNapi::CreateEnrollIntelligentVoiceEngine(napi_env env, napi_callback_info info)
181 {
182 INTELL_VOICE_LOG_INFO("enter");
183 size_t cbIndex = ARG_INDEX_1;
184
185 auto context = make_shared<AsyncContext>(env);
186 if (context == nullptr) {
187 INTELL_VOICE_LOG_ERROR("create Context failed, No memory");
188 return nullptr;
189 }
190
191 CbInfoParser parser = [env](size_t argc, napi_value *argv) -> bool {
192 CHECK_CONDITION_RETURN_FALSE((argc < ARGC_ONE), "argc less than 1");
193 napi_valuetype valueType = napi_undefined;
194 napi_typeof(env, argv[0], &valueType);
195 CHECK_CONDITION_RETURN_FALSE((valueType != napi_object), "arg type mismatch");
196 napi_value temp = nullptr;
197 napi_status status = napi_get_named_property(env, argv[0], "wakeupPhrase", &temp);
198 CHECK_CONDITION_RETURN_FALSE((status != napi_ok), "get property failed");
199 status = GetValue(env, temp, g_enrollEngineDesc_.wakeupPhrase);
200 CHECK_CONDITION_RETURN_FALSE((status != napi_ok), "get wakeup phrase failed");
201 return true;
202 };
203
204 context->result_ = (context->GetCbInfo(env, info, cbIndex, parser) ? NAPI_INTELLIGENT_VOICE_SUCCESS :
205 NAPI_INTELLIGENT_VOICE_INVALID_PARAM);
206
207 AsyncExecute execute = [](napi_env env, void *data) {};
208
209 context->complete_ = [](napi_env env, AsyncContext *asyncContext, napi_value &result) {
210 napi_value constructor = nullptr;
211 napi_status status = napi_get_reference_value(env, g_enrollEngineConstructor, &constructor);
212 if (status != napi_ok) {
213 asyncContext->result_ = NAPI_INTELLIGENT_VOICE_NO_MEMORY;
214 napi_get_undefined(env, &result);
215 return;
216 }
217
218 status = napi_new_instance(env, constructor, 0, nullptr, &result);
219 asyncContext->result_ = constructResult_;
220 if (status != napi_ok) {
221 napi_get_undefined(env, &result);
222 }
223 };
224
225 return NapiAsync::AsyncWork(env, context, "CreateEnrollIntelligentVoiceEngine", execute);
226 }
227
GetSupportedRegions(napi_env env,napi_callback_info info)228 napi_value EnrollIntellVoiceEngineNapi::GetSupportedRegions(napi_env env, napi_callback_info info)
229 {
230 INTELL_VOICE_LOG_INFO("enter");
231 size_t cbIndex = ARG_INDEX_0;
232 shared_ptr<AsyncContext> context = make_shared<AsyncContext>(env);
233 if (context == nullptr) {
234 INTELL_VOICE_LOG_ERROR("create AsyncContext failed, No memory");
235 return nullptr;
236 }
237
238 context->result_ = (context->GetCbInfo(env, info, cbIndex, nullptr) ? NAPI_INTELLIGENT_VOICE_SUCCESS :
239 NAPI_INTELLIGENT_VOICE_INVALID_PARAM);
240
241 AsyncExecute execute = [](napi_env env, void *data) {};
242
243 context->complete_ = [](napi_env env, AsyncContext *asyncContext, napi_value &result) {
244 napi_create_array(env, &result);
245 napi_set_element(env, result, 0, SetValue(env, "CN"));
246 };
247
248 return NapiAsync::AsyncWork(env, context, "GetSupportedRegions", execute);
249 }
250
Init(napi_env env,napi_callback_info info)251 napi_value EnrollIntellVoiceEngineNapi::Init(napi_env env, napi_callback_info info)
252 {
253 INTELL_VOICE_LOG_INFO("enter");
254 size_t cbIndex = ARG_INDEX_1;
255 auto context = make_shared<EnrollAsyncContext>(env);
256 if (context == nullptr) {
257 INTELL_VOICE_LOG_ERROR("create InitContext failed, No memory");
258 return nullptr;
259 }
260
261 CbInfoParser parser = [env, context](size_t argc, napi_value *argv) -> bool {
262 CHECK_CONDITION_RETURN_FALSE((argc < ARGC_ONE), "argc less than 1");
263 napi_valuetype valueType = napi_undefined;
264 napi_typeof(env, argv[0], &valueType);
265 CHECK_CONDITION_RETURN_FALSE((valueType != napi_object), "arg type mismatch");
266 napi_value temp = nullptr;
267 napi_status status = napi_get_named_property(env, argv[0], "language", &temp);
268 CHECK_CONDITION_RETURN_FALSE((status != napi_ok), "get property failed");
269 status = GetValue(env, temp,
270 reinterpret_cast<EnrollIntellVoiceEngineNapi *>(context->instanceNapi_)->config_.language);
271 CHECK_CONDITION_RETURN_FALSE((status != napi_ok), "get language failed");
272 status = napi_get_named_property(env, argv[0], "region", &temp);
273 CHECK_CONDITION_RETURN_FALSE((status != napi_ok), "get property failed");
274 status = GetValue(env, temp,
275 reinterpret_cast<EnrollIntellVoiceEngineNapi *>(context->instanceNapi_)->config_.region);
276 CHECK_CONDITION_RETURN_FALSE((status != napi_ok), "get region failed");
277 return true;
278 };
279
280 context->result_ = (context->GetCbInfo(env, info, cbIndex, parser) ? NAPI_INTELLIGENT_VOICE_SUCCESS :
281 NAPI_INTELLIGENT_VOICE_INVALID_PARAM);
282
283 context->type = ASYNC_WORK_INIT;
284 context->callbackInfo.result = UNKNOWN_ERROR;
285 context->processWork = [&](AsyncContext *asyncContext) -> int32_t {
286 auto engineNapi = reinterpret_cast<EnrollIntellVoiceEngineNapi *>(asyncContext->instanceNapi_);
287 auto engine = engineNapi->engine_;
288 if (engine == nullptr) {
289 INTELL_VOICE_LOG_ERROR("get engine instance failed");
290 asyncContext->result_ = NAPI_INTELLIGENT_VOICE_INIT_FAILED;
291 return -1;
292 }
293
294 auto ret = engine->Init(engineNapi->config_);
295 if (ret != 0) {
296 asyncContext->result_ = NAPI_INTELLIGENT_VOICE_INIT_FAILED;
297 }
298 return ret;
299 };
300
301 AsyncExecute execute = [](napi_env env, void *data) {};
302
303 return NapiAsync::AsyncWork(env, context, "Init", execute, CompleteCallback);
304 }
305
EnrollForResult(napi_env env,napi_callback_info info)306 napi_value EnrollIntellVoiceEngineNapi::EnrollForResult(napi_env env, napi_callback_info info)
307 {
308 INTELL_VOICE_LOG_INFO("enter");
309 size_t cbIndex = ARG_INDEX_1;
310 auto context = make_shared<EnrollAsyncContext>(env);
311 if (context == nullptr) {
312 INTELL_VOICE_LOG_ERROR("create StartContext failed, No memory");
313 return nullptr;
314 }
315
316 CbInfoParser parser = [env, context](size_t argc, napi_value *argv) -> bool {
317 CHECK_CONDITION_RETURN_FALSE((argc < ARGC_ONE), "argc less than 1");
318 napi_status status = GetValue(env, argv[0],
319 reinterpret_cast<EnrollIntellVoiceEngineNapi *>(context->instanceNapi_)->isLast_);
320 CHECK_CONDITION_RETURN_FALSE((status != napi_ok), "Failed to get isLast");
321 return true;
322 };
323
324 context->result_ = (context->GetCbInfo(env, info, cbIndex, parser) ? NAPI_INTELLIGENT_VOICE_SUCCESS :
325 NAPI_INTELLIGENT_VOICE_INVALID_PARAM);
326
327 context->type = ASYNC_WORK_START;
328 context->callbackInfo.result = UNKNOWN_ERROR;
329 context->processWork = [&](AsyncContext *asyncContext) {
330 EnrollIntellVoiceEngineNapi *engineNapi = reinterpret_cast<EnrollIntellVoiceEngineNapi *>(
331 asyncContext->instanceNapi_);
332 auto engine = engineNapi->engine_;
333 if (engine == nullptr) {
334 INTELL_VOICE_LOG_ERROR("get engine instance failed");
335 asyncContext->result_ = NAPI_INTELLIGENT_VOICE_PERMISSION_DENIED;
336 return -1;
337 }
338
339 auto ret = engine->Start(engineNapi->isLast_);
340 asyncContext->result_ = IntellVoiceCommonNapi::ConvertResultCode(ret);
341 return ret;
342 };
343
344 AsyncExecute execute = [](napi_env env, void *data) {};
345
346 return NapiAsync::AsyncWork(env, context, "Start", execute, CompleteCallback);
347 }
348
Stop(napi_env env,napi_callback_info info)349 napi_value EnrollIntellVoiceEngineNapi::Stop(napi_env env, napi_callback_info info)
350 {
351 INTELL_VOICE_LOG_INFO("enter");
352 size_t cbIndex = ARG_INDEX_0;
353 auto context = make_shared<AsyncContext>(env);
354 if (context == nullptr) {
355 INTELL_VOICE_LOG_ERROR("create AsyncContext failed, No memory");
356 return nullptr;
357 }
358
359 context->result_ = (context->GetCbInfo(env, info, cbIndex, nullptr) ? NAPI_INTELLIGENT_VOICE_SUCCESS :
360 NAPI_INTELLIGENT_VOICE_INVALID_PARAM);
361
362 auto cb = reinterpret_cast<EnrollIntellVoiceEngineNapi *>(context->instanceNapi_)->callbackNapi_;
363 if (cb != nullptr) {
364 cb->ClearAsyncWork(false, "the requests was aborted because user called stop");
365 }
366
367 AsyncExecute execute;
368 if (context->result_ == NAPI_INTELLIGENT_VOICE_SUCCESS) {
369 execute = [](napi_env env, void *data) {
370 CHECK_CONDITION_RETURN_VOID((data == nullptr), "data is nullptr");
371 auto asyncContext = static_cast<AsyncContext *>(data);
372 auto engine = reinterpret_cast<EnrollIntellVoiceEngineNapi *>(asyncContext->instanceNapi_)->engine_;
373 CHECK_CONDITION_RETURN_VOID((engine == nullptr), "get engine instance failed");
374 engine->Stop();
375 };
376 } else {
377 execute = [](napi_env env, void *data) {};
378 }
379
380 return NapiAsync::AsyncWork(env, context, "Stop", execute);
381 }
382
SetParameter(napi_env env,napi_callback_info info)383 napi_value EnrollIntellVoiceEngineNapi::SetParameter(napi_env env, napi_callback_info info)
384 {
385 INTELL_VOICE_LOG_INFO("enter");
386 size_t cbIndex = ARG_INDEX_2;
387 class SetParameterContext : public AsyncContext {
388 public:
389 explicit SetParameterContext(napi_env napiEnv): AsyncContext(napiEnv) {};
390 string key;
391 string value;
392 };
393 auto context = make_shared<SetParameterContext>(env);
394 if (context == nullptr) {
395 INTELL_VOICE_LOG_ERROR("create SetParameterContext failed, No memory");
396 return nullptr;
397 }
398
399 CbInfoParser parser = [env, context](size_t argc, napi_value *argv) -> bool {
400 CHECK_CONDITION_RETURN_FALSE((argc < ARGC_TWO), "argc less than 2");
401 napi_status status = GetValue(env, argv[0], context->key);
402 CHECK_CONDITION_RETURN_FALSE((status != napi_ok), "Failed to get key");
403 status = GetValue(env, argv[1], context->value);
404 CHECK_CONDITION_RETURN_FALSE((status != napi_ok), "Failed to get value");
405 return true;
406 };
407
408 context->result_ = (context->GetCbInfo(env, info, cbIndex, parser) ? NAPI_INTELLIGENT_VOICE_SUCCESS :
409 NAPI_INTELLIGENT_VOICE_INVALID_PARAM);
410
411 AsyncExecute execute;
412 if (context->result_ == NAPI_INTELLIGENT_VOICE_SUCCESS) {
413 execute = [](napi_env env, void *data) {
414 CHECK_CONDITION_RETURN_VOID((data == nullptr), "data is nullptr");
415 auto asyncContext = static_cast<SetParameterContext *>(data);
416 auto engine = reinterpret_cast<EnrollIntellVoiceEngineNapi *>(asyncContext->instanceNapi_)->engine_;
417 CHECK_CONDITION_RETURN_VOID((engine == nullptr), "get engine instance failed");
418 engine->SetParameter(asyncContext->key, asyncContext->value);
419 };
420 } else {
421 execute = [](napi_env env, void *data) {};
422 }
423
424 return NapiAsync::AsyncWork(env, context, "SetParameter", execute);
425 }
426
GetParameter(napi_env env,napi_callback_info info)427 napi_value EnrollIntellVoiceEngineNapi::GetParameter(napi_env env, napi_callback_info info)
428 {
429 INTELL_VOICE_LOG_INFO("enter");
430 size_t cbIndex = ARG_INDEX_1;
431 class GetParamContext : public AsyncContext {
432 public:
433 explicit GetParamContext(napi_env env) : AsyncContext(env) {};
434 std::string key;
435 std::string value;
436 };
437
438 auto context = make_shared<GetParamContext>(env);
439 if (context == nullptr) {
440 INTELL_VOICE_LOG_ERROR("create AsyncContext failed, No memory");
441 return nullptr;
442 }
443
444 CbInfoParser parser = [env, context](size_t argc, napi_value *argv) -> bool {
445 CHECK_CONDITION_RETURN_FALSE((argc < ARGC_ONE), "argc less than 1");
446 napi_status status = GetValue(env, argv[0], context->key);
447 CHECK_CONDITION_RETURN_FALSE((status != napi_ok), "Failed to get key");
448 return true;
449 };
450
451 context->result_ = (context->GetCbInfo(env, info, cbIndex, parser) ? NAPI_INTELLIGENT_VOICE_SUCCESS :
452 NAPI_INTELLIGENT_VOICE_INVALID_PARAM);
453
454 AsyncExecute execute;
455 if (context->result_ == NAPI_INTELLIGENT_VOICE_SUCCESS) {
456 execute = [](napi_env env, void *data) {
457 CHECK_CONDITION_RETURN_VOID((data == nullptr), "data is nullptr");
458 auto asyncContext = reinterpret_cast<GetParamContext *>(data);
459 auto engine = reinterpret_cast<EnrollIntellVoiceEngineNapi *>(asyncContext->instanceNapi_)->engine_;
460 CHECK_CONDITION_RETURN_VOID((engine == nullptr), "get engine instance failed");
461 asyncContext->value = engine->GetParameter(asyncContext->key);
462 };
463 context->complete_ = [](napi_env env, AsyncContext *asyncContext, napi_value &result) {
464 auto getParamAsynContext = reinterpret_cast<GetParamContext *>(asyncContext);
465 if (getParamAsynContext != nullptr) {
466 result = SetValue(env, getParamAsynContext->value);
467 }
468 };
469 } else {
470 execute = [](napi_env env, void *data) {};
471 }
472
473 return NapiAsync::AsyncWork(env, context, "GetParameter", execute);
474 }
475
SetSensibility(napi_env env,napi_callback_info info)476 napi_value EnrollIntellVoiceEngineNapi::SetSensibility(napi_env env, napi_callback_info info)
477 {
478 INTELL_VOICE_LOG_INFO("enter");
479 size_t cbIndex = ARG_INDEX_1;
480 class SetSensibilityContext : public AsyncContext {
481 public:
482 explicit SetSensibilityContext(napi_env napiEnv) : AsyncContext(napiEnv) {};
483 int32_t sensibility = 1;
484 };
485 auto context = make_shared<SetSensibilityContext>(env);
486 if (context == nullptr) {
487 INTELL_VOICE_LOG_ERROR("create SetSensibilityContext failed, No memory");
488 return nullptr;
489 }
490
491 CbInfoParser parser = [env, context](size_t argc, napi_value *argv) -> bool {
492 CHECK_CONDITION_RETURN_FALSE((argc < ARGC_ONE), "argc less than 1");
493 napi_status status = GetValue(env, argv[0], context->sensibility);
494 CHECK_CONDITION_RETURN_FALSE((status != napi_ok), "Failed to get sensibility");
495 return true;
496 };
497
498 context->result_ = (context->GetCbInfo(env, info, cbIndex, parser) ? NAPI_INTELLIGENT_VOICE_SUCCESS :
499 NAPI_INTELLIGENT_VOICE_INVALID_PARAM);
500
501 AsyncExecute execute = [](napi_env env, void *data) {
502 CHECK_CONDITION_RETURN_VOID((data == nullptr), "data is nullptr");
503 auto asyncContext = static_cast<SetSensibilityContext *>(data);
504 CHECK_CONDITION_RETURN_VOID((asyncContext->result_ != NAPI_INTELLIGENT_VOICE_SUCCESS), "no need to execute");
505 auto engine = reinterpret_cast<EnrollIntellVoiceEngineNapi *>(asyncContext->instanceNapi_)->engine_;
506 CHECK_CONDITION_RETURN_VOID((engine == nullptr), "get engine instance failed");
507 engine->SetSensibility(asyncContext->sensibility);
508 };
509
510 return NapiAsync::AsyncWork(env, context, "SetSensibility", execute);
511 }
512
SetWakeupHapInfo(napi_env env,napi_callback_info info)513 napi_value EnrollIntellVoiceEngineNapi::SetWakeupHapInfo(napi_env env, napi_callback_info info)
514 {
515 INTELL_VOICE_LOG_INFO("enter");
516 size_t cbIndex = ARG_INDEX_1;
517 class SetWakeupHapContext : public AsyncContext {
518 public:
519 explicit SetWakeupHapContext(napi_env napiEnv) : AsyncContext(napiEnv) {};
520 WakeupHapInfo hapInfo;
521 };
522 auto context = make_shared<SetWakeupHapContext>(env);
523 if (context == nullptr) {
524 INTELL_VOICE_LOG_ERROR("create SetWakeupHapContext failed, No memory");
525 return nullptr;
526 }
527
528 CbInfoParser parser = [env, context](size_t argc, napi_value *argv) -> bool {
529 CHECK_CONDITION_RETURN_FALSE((argc < ARGC_ONE), "argc less than 1");
530 napi_value temp = nullptr;
531 napi_status status = napi_get_named_property(env, argv[0], "bundleName", &temp);
532 CHECK_CONDITION_RETURN_FALSE((status != napi_ok), "get property failed");
533 status = GetValue(env, temp, context->hapInfo.bundleName);
534 CHECK_CONDITION_RETURN_FALSE((status != napi_ok), "get bundle name failed");
535 status = napi_get_named_property(env, argv[0], "abilityName", &temp);
536 CHECK_CONDITION_RETURN_FALSE((status != napi_ok), "get property failed");
537 status = GetValue(env, temp, context->hapInfo.abilityName);
538 CHECK_CONDITION_RETURN_FALSE((status != napi_ok), "get ability name failed");
539 return true;
540 };
541
542 context->result_ = (context->GetCbInfo(env, info, cbIndex, parser) ? NAPI_INTELLIGENT_VOICE_SUCCESS :
543 NAPI_INTELLIGENT_VOICE_INVALID_PARAM);
544
545 AsyncExecute execute = [](napi_env env, void *data) {
546 CHECK_CONDITION_RETURN_VOID((data == nullptr), "data is nullptr");
547 auto asyncContext = static_cast<SetWakeupHapContext *>(data);
548 CHECK_CONDITION_RETURN_VOID((asyncContext->result_ != NAPI_INTELLIGENT_VOICE_SUCCESS), "no need to execute");
549 auto engine = reinterpret_cast<EnrollIntellVoiceEngineNapi *>(asyncContext->instanceNapi_)->engine_;
550 CHECK_CONDITION_RETURN_VOID((engine == nullptr), "get engine instance failed");
551 engine->SetWakeupHapInfo(asyncContext->hapInfo);
552 };
553
554 return NapiAsync::AsyncWork(env, context, "SetWakeupHapInfo", execute);
555 }
556
Commit(napi_env env,napi_callback_info info)557 napi_value EnrollIntellVoiceEngineNapi::Commit(napi_env env, napi_callback_info info)
558 {
559 INTELL_VOICE_LOG_INFO("enter");
560 size_t cbIndex = ARG_INDEX_0;
561 auto context = make_shared<EnrollAsyncContext>(env);
562 if (context == nullptr) {
563 INTELL_VOICE_LOG_ERROR("create IntellVoiceContext failed, No memory");
564 return nullptr;
565 }
566
567 context->result_ = (context->GetCbInfo(env, info, cbIndex, nullptr) ? NAPI_INTELLIGENT_VOICE_SUCCESS :
568 NAPI_INTELLIGENT_VOICE_INVALID_PARAM);
569
570 context->type = ASYNC_WORK_COMMIT;
571 context->callbackInfo.result = UNKNOWN_ERROR;
572 context->processWork = [&](AsyncContext *asyncContext) {
573 auto engineNapi = reinterpret_cast<EnrollIntellVoiceEngineNapi *>(asyncContext->instanceNapi_);
574 auto engine = engineNapi->engine_;
575 if (engine == nullptr) {
576 INTELL_VOICE_LOG_ERROR("get engine instance failed");
577 asyncContext->result_ = NAPI_INTELLIGENT_VOICE_COMMIT_ENROLL_FAILED;
578 return -1;
579 }
580
581 auto ret = engine->Commit();
582 if (ret != 0) {
583 asyncContext->result_ = NAPI_INTELLIGENT_VOICE_COMMIT_ENROLL_FAILED;
584 }
585 return ret;
586 };
587
588 AsyncExecute execute = [](napi_env env, void *data) {};
589
590 return NapiAsync::AsyncWork(env, context, "Commit", execute, CompleteCallback);
591 }
592
EvaluateForResult(napi_env env,napi_callback_info info)593 napi_value EnrollIntellVoiceEngineNapi::EvaluateForResult(napi_env env, napi_callback_info info)
594 {
595 INTELL_VOICE_LOG_INFO("enter");
596 size_t cbIndex = ARG_INDEX_1;
597 auto context = make_shared<EvaluateContext>(env);
598 if (context == nullptr) {
599 INTELL_VOICE_LOG_ERROR("create EvaluateContext failed, No memory");
600 return nullptr;
601 }
602
603 CbInfoParser parser = [env, context](size_t argc, napi_value *argv) -> bool {
604 CHECK_CONDITION_RETURN_FALSE((argc < ARGC_ONE), "argc less than 1");
605 CHECK_CONDITION_RETURN_FALSE((GetValue(env, argv[ARG_INDEX_0], context->word) != napi_ok),
606 "failed to get word");
607 return true;
608 };
609
610 context->result_ = (context->GetCbInfo(env, info, cbIndex, parser) ? NAPI_INTELLIGENT_VOICE_SUCCESS :
611 NAPI_INTELLIGENT_VOICE_INVALID_PARAM);
612
613 AsyncExecute execute;
614 if (context->result_ == NAPI_INTELLIGENT_VOICE_SUCCESS) {
615 execute = [](napi_env env, void *data) {
616 CHECK_CONDITION_RETURN_VOID((data == nullptr), "data is nullptr");
617 auto context = static_cast<EvaluateContext *>(data);
618 auto engine = reinterpret_cast<EnrollIntellVoiceEngineNapi *>(context->instanceNapi_)->engine_;
619 if (engine == nullptr) {
620 INTELL_VOICE_LOG_ERROR("engine is nullptr");
621 context->result_ = NAPI_INTELLIGENT_VOICE_NO_MEMORY;
622 return;
623 }
624 auto ret = engine->Evaluate(context->word, context->info);
625 if (ret != 0) {
626 INTELL_VOICE_LOG_ERROR("failed to evaluate");
627 context->result_ = NAPI_INTELLIGENT_VOICE_SYSTEM_ERROR;
628 }
629 };
630 } else {
631 execute = [](napi_env env, void *data) {};
632 }
633
634 context->complete_ = [](napi_env env, AsyncContext *asyncContext, napi_value &result) {
635 auto context = static_cast<EvaluateContext *>(asyncContext);
636 napi_status status = napi_create_object(env, &result);
637 if (status != napi_ok || result == nullptr) {
638 INTELL_VOICE_LOG_ERROR("failed to create object, status: %{public}d", status);
639 context->result_ = NAPI_INTELLIGENT_VOICE_NO_MEMORY;
640 return;
641 }
642 napi_set_named_property(env, result, "score", SetValue(env, context->info.score));
643 napi_set_named_property(env, result, "resultCode", SetValue(env, context->info.resultCode));
644 };
645 return NapiAsync::AsyncWork(env, context, "Evaluate", execute);
646 }
647
Release(napi_env env,napi_callback_info info)648 napi_value EnrollIntellVoiceEngineNapi::Release(napi_env env, napi_callback_info info)
649 {
650 INTELL_VOICE_LOG_INFO("enter");
651 size_t cbIndex = ARG_INDEX_0;
652 shared_ptr<AsyncContext> context = make_shared<AsyncContext>(env);
653 if (context == nullptr) {
654 INTELL_VOICE_LOG_ERROR("create AsyncContext failed, No memory");
655 return nullptr;
656 }
657
658 context->result_ = (context->GetCbInfo(env, info, cbIndex, nullptr) ? NAPI_INTELLIGENT_VOICE_SUCCESS :
659 NAPI_INTELLIGENT_VOICE_INVALID_PARAM);
660
661 AsyncExecute execute;
662 if (context->result_ == NAPI_INTELLIGENT_VOICE_SUCCESS) {
663 execute = [](napi_env env, void *data) {
664 CHECK_CONDITION_RETURN_VOID((data == nullptr), "data is nullptr");
665 auto asyncContext = static_cast<AsyncContext *>(data);
666 auto cb = reinterpret_cast<EnrollIntellVoiceEngineNapi *>(asyncContext->instanceNapi_)->callbackNapi_;
667 if (cb != nullptr) {
668 cb->ClearAsyncWork(false, "the requests was aborted because user called release");
669 }
670 auto engine = reinterpret_cast<EnrollIntellVoiceEngineNapi *>(asyncContext->instanceNapi_)->engine_;
671 CHECK_CONDITION_RETURN_VOID((engine == nullptr), "get engine instance failed");
672 engine->Release();
673 reinterpret_cast<EnrollIntellVoiceEngineNapi *>(asyncContext->instanceNapi_)->engine_ = nullptr;
674 reinterpret_cast<EnrollIntellVoiceEngineNapi *>(asyncContext->instanceNapi_)->callbackNapi_ = nullptr;
675 };
676 } else {
677 execute = [](napi_env env, void *data) {};
678 }
679
680 return NapiAsync::AsyncWork(env, context, "Release", execute);
681 }
682
CompleteCallback(napi_env env,napi_status status,void * data)683 void EnrollIntellVoiceEngineNapi::CompleteCallback(napi_env env, napi_status status, void *data)
684 {
685 INTELL_VOICE_LOG_INFO("enter");
686 CHECK_CONDITION_RETURN_VOID((data == nullptr), "async complete callback data is nullptr");
687 napi_value result = nullptr;
688
689 auto asyncContext = static_cast<EnrollAsyncContext *>(data);
690 if (asyncContext->result_ != NAPI_INTELLIGENT_VOICE_SUCCESS) {
691 napi_get_undefined(env, &result);
692 NapiAsync::CommonCallbackRoutine(env, asyncContext, result);
693 return;
694 }
695
696 if (asyncContext->processWork == nullptr) {
697 INTELL_VOICE_LOG_ERROR("process work is nullptr");
698 napi_get_undefined(env, &result);
699 asyncContext->result_ = NAPI_INTELLIGENT_VOICE_NO_MEMORY;
700 NapiAsync::CommonCallbackRoutine(env, asyncContext, result);
701 return;
702 }
703
704 auto cb = reinterpret_cast<EnrollIntellVoiceEngineNapi *>(asyncContext->instanceNapi_)->callbackNapi_;
705 if (cb == nullptr) {
706 INTELL_VOICE_LOG_ERROR("get callback napi failed");
707 napi_get_undefined(env, &result);
708 asyncContext->result_ = NAPI_INTELLIGENT_VOICE_NO_MEMORY;
709 NapiAsync::CommonCallbackRoutine(env, asyncContext, result);
710 return;
711 }
712
713 cb->QueueAsyncWork(asyncContext);
714 if (asyncContext->processWork(asyncContext) != 0) {
715 INTELL_VOICE_LOG_ERROR("process work failed");
716 cb->ClearAsyncWork(true, "the request was aborted because intelligent voice processWork error");
717 }
718 }
719 } // namespace IntellVoiceNapi
720 } // namespace OHOS
721