• 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 
16 #include "enroll_intell_voice_engine_callback_napi.h"
17 #include "intell_voice_log.h"
18 #include "intell_voice_common_napi.h"
19 
20 #define LOG_TAG "EnrollEngineCallbackNapi"
21 
22 using namespace std;
23 using namespace OHOS::IntellVoiceEngine;
24 using namespace OHOS::HDI::IntelligentVoice::Engine::V1_0;
25 
26 namespace OHOS {
27 namespace IntellVoiceNapi {
GetCallBackInfoNapiValue(const napi_env & env,napi_value & out)28 void EnrollCallbackInfo::GetCallBackInfoNapiValue(const napi_env &env, napi_value &out)
29 {
30     napi_status status = napi_create_object(env, &out);
31     if (status != napi_ok || out == nullptr) {
32         INTELL_VOICE_LOG_ERROR("failed to create js callbackInfo, error: %{public}d", status);
33         return;
34     }
35 
36     napi_set_named_property(env, out, "result", SetValue(env, result));
37     napi_set_named_property(env, out, "context", SetValue(env, context));
38 }
39 
EnrollIntellVoiceEngineCallbackNapi(const napi_env env)40 EnrollIntellVoiceEngineCallbackNapi::EnrollIntellVoiceEngineCallbackNapi(const napi_env env) : env_(env)
41 {
42     if (env_ != nullptr) {
43         napi_get_uv_event_loop(env_, &loop_);
44     }
45     contextMap_.clear();
46 }
47 
~EnrollIntellVoiceEngineCallbackNapi()48 EnrollIntellVoiceEngineCallbackNapi::~EnrollIntellVoiceEngineCallbackNapi()
49 {
50     contextMap_.clear();
51 }
52 
QueueAsyncWork(EnrollAsyncContext * context)53 void EnrollIntellVoiceEngineCallbackNapi::QueueAsyncWork(EnrollAsyncContext *context)
54 {
55     std::lock_guard<std::mutex> lock(mutex_);
56     if (contextMap_.find(context->type) == contextMap_.end()) {
57         std::queue<EnrollAsyncContext *> contextQue;
58         contextQue.push(context);
59         contextMap_[context->type] = contextQue;
60     } else {
61         contextMap_.at(context->type).push(context);
62     }
63 }
64 
ConvertEventId(EnrollAsyncWorkType type)65 int32_t EnrollIntellVoiceEngineCallbackNapi::ConvertEventId(EnrollAsyncWorkType type)
66 {
67     int32_t eventId = HDI::IntelligentVoice::Engine::V1_0::INTELL_VOICE_ENGINE_MSG_NONE;
68     switch (type) {
69         case ASYNC_WORK_INIT:
70             eventId = HDI::IntelligentVoice::Engine::V1_0::INTELL_VOICE_ENGINE_MSG_INIT_DONE;
71             break;
72         case ASYNC_WORK_START:
73             eventId = HDI::IntelligentVoice::Engine::V1_0::INTELL_VOICE_ENGINE_MSG_ENROLL_COMPLETE;
74             break;
75         case ASYNC_WORK_COMMIT:
76             eventId = HDI::IntelligentVoice::Engine::V1_0::INTELL_VOICE_ENGINE_MSG_COMMIT_ENROLL_COMPLETE;
77             break;
78         default:
79             break;
80     }
81 
82     return eventId;
83 }
84 
ClearAsyncWork(bool error,const std::string & msg)85 void EnrollIntellVoiceEngineCallbackNapi::ClearAsyncWork(bool error, const std::string &msg)
86 {
87     INTELL_VOICE_LOG_INFO("%{public}s", msg.c_str());
88     std::lock_guard<std::mutex> lock(mutex_);
89     for (auto it = contextMap_.begin(); it != contextMap_.end(); it++) {
90         auto &contextQue = it->second;
91         int32_t eventId = ConvertEventId(it->first);
92         while (!contextQue.empty()) {
93             EnrollAsyncContext *context = contextQue.front();
94             contextQue.pop();
95             if (error) {
96                 INTELL_VOICE_LOG_WARN("error occured");
97             }
98             if (context == nullptr) {
99                 continue;
100             }
101 
102             context->callbackInfo.eventId = eventId;
103             if (eventId == static_cast<int32_t>(INTELL_VOICE_ENGINE_MSG_INIT_DONE)) {
104                 context->result_ = NAPI_INTELLIGENT_VOICE_INIT_FAILED;
105             } else if (eventId == static_cast<int32_t>(INTELL_VOICE_ENGINE_MSG_ENROLL_COMPLETE)) {
106                 context->result_ = NAPI_INTELLIGENT_VOICE_SUCCESS;
107                 context->callbackInfo.result = UNKNOWN_ERROR;
108                 context->callbackInfo.context = "";
109             } else if (eventId == static_cast<int32_t>(INTELL_VOICE_ENGINE_MSG_COMMIT_ENROLL_COMPLETE)) {
110                 context->result_ = NAPI_INTELLIGENT_VOICE_COMMIT_ENROLL_FAILED;
111             } else {
112                 INTELL_VOICE_LOG_WARN("invalid type:%{public}d", it->first);
113                 continue;
114             }
115 
116             OnJsCallBack(context);
117         }
118     }
119     contextMap_.clear();
120 }
121 
OnEvent(const IntellVoiceEngineCallBackEvent & event)122 void EnrollIntellVoiceEngineCallbackNapi::OnEvent(const IntellVoiceEngineCallBackEvent &event)
123 {
124     INTELL_VOICE_LOG_INFO("OnEvent: msgId: %{public}d, errCode: %{public}d", event.msgId, event.result);
125     EnrollAsyncWorkType asyncType = ASYNC_WORK_INVALID;
126     switch (event.msgId) {
127         case HDI::IntelligentVoice::Engine::V1_0::INTELL_VOICE_ENGINE_MSG_INIT_DONE:
128             asyncType = ASYNC_WORK_INIT;
129             break;
130         case HDI::IntelligentVoice::Engine::V1_0::INTELL_VOICE_ENGINE_MSG_ENROLL_COMPLETE:
131             asyncType = ASYNC_WORK_START;
132             break;
133         case HDI::IntelligentVoice::Engine::V1_0::INTELL_VOICE_ENGINE_MSG_COMMIT_ENROLL_COMPLETE:
134             asyncType = ASYNC_WORK_COMMIT;
135             break;
136         default:
137             break;
138     }
139     std::lock_guard<std::mutex> lock(mutex_);
140     if (contextMap_.find(asyncType) == contextMap_.end() || contextMap_.at(asyncType).empty()) {
141         INTELL_VOICE_LOG_ERROR("callback is called, But context is empty");
142         return;
143     }
144 
145     EnrollAsyncContext *context = contextMap_.at(asyncType).front();
146     contextMap_.at(asyncType).pop();
147     if (context == nullptr) {
148         INTELL_VOICE_LOG_ERROR("context is nullptr");
149         return;
150     }
151 
152     context->callbackInfo = {event.msgId, event.result, event.info};
153     if (event.result != 0) {
154         if (event.msgId == INTELL_VOICE_ENGINE_MSG_INIT_DONE) {
155             context->result_ = NAPI_INTELLIGENT_VOICE_INIT_FAILED;
156         } else if (event.msgId == INTELL_VOICE_ENGINE_MSG_COMMIT_ENROLL_COMPLETE) {
157             context->result_ = NAPI_INTELLIGENT_VOICE_COMMIT_ENROLL_FAILED;
158         }
159     }
160     OnJsCallBack(context);
161 }
162 
UvWorkCallBack(uv_work_t * work,int status)163 void EnrollIntellVoiceEngineCallbackNapi::UvWorkCallBack(uv_work_t *work, int status)
164 {
165     INTELL_VOICE_LOG_INFO("enter");
166     auto asyncContext = reinterpret_cast<EnrollAsyncContext *>(work->data);
167     napi_value result = nullptr;
168     if (asyncContext != nullptr) {
169         napi_env env = asyncContext->env_;
170         if (asyncContext->callbackInfo.eventId ==
171             HDI::IntelligentVoice::Engine::V1_0::INTELL_VOICE_ENGINE_MSG_ENROLL_COMPLETE) {
172             asyncContext->callbackInfo.GetCallBackInfoNapiValue(env, result);
173         } else {
174             napi_get_undefined(env, &result);
175         }
176         NapiAsync::CommonCallbackRoutine(env, asyncContext, result);
177     }
178 
179     delete work;
180 }
181 
OnJsCallBack(EnrollAsyncContext * context)182 void EnrollIntellVoiceEngineCallbackNapi::OnJsCallBack(EnrollAsyncContext *context)
183 {
184     INTELL_VOICE_LOG_INFO("enter, event id:%{public}d", context->callbackInfo.eventId);
185     if (loop_ != nullptr) {
186         uv_work_t *work = new (std::nothrow) uv_work_t;
187         if (work != nullptr) {
188             work->data = reinterpret_cast<void *>(context);
189             int ret = uv_queue_work(
190                 loop_, work, [](uv_work_t *work) {}, UvWorkCallBack);
191             if (ret != 0) {
192                 INTELL_VOICE_LOG_INFO("Failed to execute libuv work queue");
193                 context->contextSp_.reset();
194                 delete work;
195             }
196         } else {
197             context->contextSp_.reset();
198         }
199     } else {
200         context->contextSp_.reset();
201     }
202 }
203 }  // namespace IntellVoiceNapi
204 }  // namespace OHOS