• 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, context: %{public}s",
125         event.msgId, event.result, event.info.c_str());
126     EnrollAsyncWorkType asyncType = ASYNC_WORK_INVALID;
127     switch (event.msgId) {
128         case HDI::IntelligentVoice::Engine::V1_0::INTELL_VOICE_ENGINE_MSG_INIT_DONE:
129             asyncType = ASYNC_WORK_INIT;
130             break;
131         case HDI::IntelligentVoice::Engine::V1_0::INTELL_VOICE_ENGINE_MSG_ENROLL_COMPLETE:
132             asyncType = ASYNC_WORK_START;
133             break;
134         case HDI::IntelligentVoice::Engine::V1_0::INTELL_VOICE_ENGINE_MSG_COMMIT_ENROLL_COMPLETE:
135             asyncType = ASYNC_WORK_COMMIT;
136             break;
137         default:
138             break;
139     }
140     std::lock_guard<std::mutex> lock(mutex_);
141     if (contextMap_.find(asyncType) == contextMap_.end() || contextMap_.at(asyncType).empty()) {
142         INTELL_VOICE_LOG_ERROR("callback is called, But context is empty");
143         return;
144     }
145 
146     EnrollAsyncContext *context = contextMap_.at(asyncType).front();
147     contextMap_.at(asyncType).pop();
148     if (context == nullptr) {
149         INTELL_VOICE_LOG_ERROR("context is nullptr");
150         return;
151     }
152 
153     context->callbackInfo = {event.msgId, event.result, event.info};
154     if (event.result != 0) {
155         if (event.msgId == INTELL_VOICE_ENGINE_MSG_INIT_DONE) {
156             context->result_ = NAPI_INTELLIGENT_VOICE_INIT_FAILED;
157         } else if (event.msgId == INTELL_VOICE_ENGINE_MSG_COMMIT_ENROLL_COMPLETE) {
158             context->result_ = NAPI_INTELLIGENT_VOICE_COMMIT_ENROLL_FAILED;
159         }
160     }
161     OnJsCallBack(context);
162 }
163 
UvWorkCallBack(uv_work_t * work,int status)164 void EnrollIntellVoiceEngineCallbackNapi::UvWorkCallBack(uv_work_t *work, int status)
165 {
166     INTELL_VOICE_LOG_INFO("enter");
167     auto asyncContext = reinterpret_cast<EnrollAsyncContext *>(work->data);
168     napi_value result = nullptr;
169     if (asyncContext != nullptr) {
170         napi_env env = asyncContext->env_;
171         if (asyncContext->callbackInfo.eventId ==
172             HDI::IntelligentVoice::Engine::V1_0::INTELL_VOICE_ENGINE_MSG_ENROLL_COMPLETE) {
173             asyncContext->callbackInfo.GetCallBackInfoNapiValue(env, result);
174         } else {
175             napi_get_undefined(env, &result);
176         }
177         NapiAsync::CommonCallbackRoutine(env, asyncContext, result);
178     }
179 
180     delete work;
181 }
182 
OnJsCallBack(EnrollAsyncContext * context)183 void EnrollIntellVoiceEngineCallbackNapi::OnJsCallBack(EnrollAsyncContext *context)
184 {
185     INTELL_VOICE_LOG_INFO("enter, event id:%{public}d", context->callbackInfo.eventId);
186     if (loop_ != nullptr) {
187         uv_work_t *work = new (std::nothrow) uv_work_t;
188         if (work != nullptr) {
189             work->data = reinterpret_cast<void *>(context);
190             int ret = uv_queue_work(
191                 loop_, work, [](uv_work_t *work) {}, UvWorkCallBack);
192             if (ret != 0) {
193                 INTELL_VOICE_LOG_INFO("Failed to execute libuv work queue");
194                 context->contextSp_.reset();
195                 delete work;
196             }
197         } else {
198             context->contextSp_.reset();
199         }
200     } else {
201         context->contextSp_.reset();
202     }
203 }
204 }  // namespace IntellVoiceNapi
205 }  // namespace OHOS