1 /*
2 * Copyright (c) 2025 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 "image_embedding_napi.h"
17
18 #include <dlfcn.h>
19
20 #include "aip_log.h"
21 #include "aip_napi_error.h"
22 #include "aip_napi_utils.h"
23 #include "i_aip_core_manager_impl.h"
24
25 #undef LOG_TAG
26 #define LOG_TAG "ImageEmbeddingNapi"
27
28 namespace OHOS {
29 namespace DataIntelligence {
30 namespace {
31 const int32_t ERR_OK = 0;
32 static constexpr uint8_t ARG_0 = 0;
33 static constexpr uint8_t ARG_1 = 1;
34 static constexpr uint8_t NUM_0 = 0;
35 static constexpr uint8_t NUM_1 = 1;
36 static constexpr uint8_t BASIC_MODEL = 0;
37 static const std::string CLASS_NAME = "ImageEmbedding";
38 const std::vector<std::string> EXPECTED_GET_ARG_TYPES = { "string" };
39 const std::vector<std::string> EXPECTED_GET_IMG_MODEL_ARG_TYPES = { "object" };
40 constexpr const char *AIP_MANAGER_PATH = "libaip_core.z.so";
41 } // namespace
42
43 AipCoreManagerHandle ImageEmbeddingNapi::imgAipCoreMgrHandle_{};
44 thread_local napi_ref ImageEmbeddingNapi::sConstructor_ = nullptr;
45 IAipCoreManager *ImageEmbeddingNapi::imageAipCoreManager_ = nullptr;
46
47 struct ImageEmbeddingConstructorInfo {
48 std::string className;
49 napi_ref *classRef;
50 napi_callback constructor;
51 const napi_property_descriptor *property;
52 size_t propertyCount;
53 const napi_property_descriptor *staticProperty;
54 size_t staticPropertyCount;
55 };
56
57 struct LoadCallbackData {
58 napi_async_work asyncWork;
59 napi_deferred deferred;
60 int32_t ret;
61 };
62
63 struct ReleaseCallbackData {
64 napi_async_work asyncWork;
65 napi_deferred deferred;
66 int32_t ret;
67 };
68
69 struct ImageCallbackData {
70 napi_async_work asyncWork;
71 napi_deferred deferred;
72 std::string strArg;
73 int32_t dataRet;
74 std::vector<float> ret;
75 };
76
ImageEmbeddingNapi()77 ImageEmbeddingNapi::ImageEmbeddingNapi() : env_(nullptr) {}
78
~ImageEmbeddingNapi()79 ImageEmbeddingNapi::~ImageEmbeddingNapi()
80 {
81 AipNapiUtils::UnLoadAlgoLibrary(imgAipCoreMgrHandle_);
82 delete imageAipCoreManager_;
83 imageAipCoreManager_ = nullptr;
84 }
85
StartInit(napi_env env,napi_value exports,struct ImageEmbeddingConstructorInfo info)86 static napi_value StartInit(napi_env env, napi_value exports, struct ImageEmbeddingConstructorInfo info)
87 {
88 napi_value constructor = nullptr;
89 napi_status status = napi_define_class(env, info.className.c_str(), NAPI_AUTO_LENGTH, info.constructor, nullptr,
90 info.propertyCount, info.property, &constructor);
91 if (status != napi_ok) {
92 AIP_HILOGE("define class fail");
93 return nullptr;
94 }
95
96 status = napi_create_reference(env, constructor, NUM_1, info.classRef);
97 if (status != napi_ok) {
98 AIP_HILOGE("create reference fail");
99 return nullptr;
100 }
101
102 napi_value global = nullptr;
103 status = napi_get_global(env, &global);
104 if (status != napi_ok) {
105 AIP_HILOGE("create global fail");
106 return nullptr;
107 }
108
109 status = napi_set_named_property(env, global, info.className.c_str(), constructor);
110 if (status != napi_ok) {
111 AIP_HILOGE("Init::set global named property fail");
112 return nullptr;
113 }
114
115 status = napi_define_properties(env, exports, info.staticPropertyCount, info.staticProperty);
116 if (status != napi_ok) {
117 AIP_HILOGE("define properties fail");
118 return nullptr;
119 }
120 return exports;
121 }
122
Init(napi_env env,napi_value exports)123 napi_value ImageEmbeddingNapi::Init(napi_env env, napi_value exports)
124 {
125 AIP_HILOGD("Enter");
126 if (!AipNapiUtils::LoadAlgoLibrary(AIP_MANAGER_PATH, imgAipCoreMgrHandle_)) {
127 AIP_HILOGE("LoadAlgoLibrary failed");
128 }
129
130 if (imgAipCoreMgrHandle_.pAipManager != nullptr) {
131 imageAipCoreManager_ = AipNapiUtils::GetAlgoObj(imgAipCoreMgrHandle_);
132 } else {
133 imageAipCoreManager_ = new (std::nothrow) IAipCoreManagerImpl();
134 }
135
136 if (imageAipCoreManager_ == nullptr) {
137 AIP_HILOGE("GetAlgoObj failed");
138 return nullptr;
139 }
140
141 napi_property_descriptor properties[] = {
142 DECLARE_NAPI_FUNCTION("loadModel", LoadModel),
143 DECLARE_NAPI_FUNCTION("releaseModel", ReleaseModel),
144 DECLARE_NAPI_FUNCTION("getEmbedding", GetEmbedding),
145 };
146
147 napi_property_descriptor static_prop[] = {
148 DECLARE_NAPI_STATIC_FUNCTION("getImageEmbeddingModel", GetImageEmbeddingModel),
149 };
150
151 struct ImageEmbeddingConstructorInfo info = {
152 .className = CLASS_NAME,
153 .classRef = &sConstructor_,
154 .constructor = Constructor,
155 .property = properties,
156 .propertyCount = sizeof(properties) / sizeof(properties[NUM_0]),
157 .staticProperty = static_prop,
158 .staticPropertyCount = sizeof(static_prop) / sizeof(static_prop[NUM_0]),
159 };
160
161 if (StartInit(env, exports, info)) {
162 return nullptr;
163 }
164 return exports;
165 }
166
Constructor(napi_env env,napi_callback_info info)167 napi_value ImageEmbeddingNapi::Constructor(napi_env env, napi_callback_info info)
168 {
169 napi_value undefineValue = nullptr;
170 napi_get_undefined(env, &undefineValue);
171
172 napi_status status;
173 napi_value thisVar = nullptr;
174 status = napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
175 if (status == napi_ok && thisVar != nullptr) {
176 std::unique_ptr<ImageEmbeddingNapi> imgEmbNapi = std::make_unique<ImageEmbeddingNapi>();
177 if (imgEmbNapi != nullptr) {
178 imgEmbNapi->env_ = env;
179 status = napi_wrap(env, thisVar, reinterpret_cast<void *>(imgEmbNapi.get()), ImageEmbeddingNapi::Destructor,
180 nullptr, nullptr);
181 if (status == napi_ok) {
182 imgEmbNapi.release();
183 return thisVar;
184 } else {
185 AIP_HILOGE("Failure wrapping js to native napi");
186 }
187 }
188 }
189 return undefineValue;
190 }
191
Destructor(napi_env env,void * nativeObject,void * finalize)192 void ImageEmbeddingNapi::Destructor(napi_env env, void *nativeObject, void *finalize)
193 {
194 AIP_HILOGD("TextEmbeddingNapi, Destructor");
195 }
196
GetImageEmbeddingModel(napi_env env,napi_callback_info info)197 napi_value ImageEmbeddingNapi::GetImageEmbeddingModel(napi_env env, napi_callback_info info)
198 {
199 AIP_HILOGE("Enter");
200 size_t argc = ARG_1;
201 napi_value args[ARG_1] = { nullptr };
202 napi_value jsThis = nullptr;
203
204 napi_status status = napi_get_cb_info(env, info, &argc, args, &jsThis, nullptr);
205 if (status != napi_ok) {
206 AIP_HILOGE("napi_get_cb_info failed");
207 ThrowIntelligenceErr(env, INNER_ERROR, "napi_get_cb_info failed.");
208 return nullptr;
209 }
210
211 if (!AipNapiUtils::ValidateArgsType(env, args, argc, EXPECTED_GET_IMG_MODEL_ARG_TYPES)) {
212 AIP_HILOGE("ValidateArgsType failed");
213 ThrowIntelligenceErr(env, PARAM_EXCEPTION, "wrong params type.");
214 return nullptr;
215 }
216
217 ModelConfigData imgModelConfig;
218 if (!ParseModelConfig(env, args, argc, &imgModelConfig)) {
219 AIP_HILOGE("ParseModelConfig failed");
220 ThrowIntelligenceErr(env, PARAM_EXCEPTION, "wrong params type.");
221 return nullptr;
222 }
223
224 napi_value promise = nullptr;
225 napi_deferred deferred = nullptr;
226 status = napi_create_promise(env, &deferred, &promise);
227 if (status != napi_ok) {
228 AIP_HILOGE("create promise failed");
229 ThrowIntelligenceErr(env, INNER_ERROR, "create promise failed");
230 return nullptr;
231 }
232
233 auto asyncGetImgEmbeddingModelData = new (std::nothrow) AsyncGetImageEmbeddingModelData{
234 .asyncWork = nullptr,
235 .deferred = deferred,
236 .config = imgModelConfig,
237 };
238 if (asyncGetImgEmbeddingModelData == nullptr) {
239 AIP_HILOGE("new asyncGetImgEmbeddingModelData error.");
240 ThrowIntelligenceErr(env, INNER_ERROR, "new asyncGetImgEmbeddingModelData failed");
241 return nullptr;
242 }
243
244 if (!CreateAsyncImgModelExecution(env, asyncGetImgEmbeddingModelData)) {
245 AIP_HILOGE("create AsyncTextModelExecution failed");
246 ThrowIntelligenceErr(env, INNER_ERROR, "create AsyncTextModelExecution failed");
247 delete asyncGetImgEmbeddingModelData;
248 return nullptr;
249 }
250
251 return promise;
252 }
253
ParseModelConfig(napi_env env,napi_value * args,size_t argc,ModelConfigData * modelConfig)254 bool ImageEmbeddingNapi::ParseModelConfig(napi_env env, napi_value *args, size_t argc, ModelConfigData *modelConfig)
255 {
256 AIP_HILOGI("Enter");
257 if (modelConfig == nullptr) {
258 AIP_HILOGE("The modelConfig is null");
259 return false;
260 }
261 if (!AipNapiUtils::CheckModelConfig(env, args[ARG_0])) {
262 AIP_HILOGE("The modelConfig is failed");
263 return false;
264 }
265
266 napi_value version;
267 napi_value isNPUAvailable;
268 napi_value cachePath;
269 napi_status status = napi_get_named_property(env, args[ARG_0], "version", &version);
270 if (status != napi_ok) {
271 AIP_HILOGE("napi get version property failed");
272 return false;
273 }
274
275 if (!AipNapiUtils::TransJsToInt32(env, version, modelConfig->versionValue)) {
276 AIP_HILOGE("Trans version failed");
277 return false;
278 }
279
280 if (modelConfig->versionValue != BASIC_MODEL) {
281 AIP_HILOGE("The version value is invalid");
282 return false;
283 }
284
285 status = napi_get_named_property(env, args[ARG_0], "isNpuAvailable", &isNPUAvailable);
286 if (status != napi_ok) {
287 AIP_HILOGE("napi get isNpuAvailable property failed");
288 return false;
289 }
290
291 if (!AipNapiUtils::TransJsToBool(env, isNPUAvailable, modelConfig->isNPUAvailableValue)) {
292 AIP_HILOGE("Trans isNPUAvailable failed");
293 return false;
294 }
295
296 if (modelConfig->isNPUAvailableValue) {
297 status = napi_get_named_property(env, args[ARG_0], "cachePath", &cachePath);
298 if (status != napi_ok) {
299 AIP_HILOGE("napi get cachePath property failed");
300 return false;
301 }
302
303 if (!AipNapiUtils::TransJsToStr(env, cachePath, modelConfig->cachePathValue)) {
304 AIP_HILOGE("Trans cachePath failed");
305 return false;
306 }
307 } else {
308 modelConfig->cachePathValue = "";
309 }
310 return true;
311 }
312
313
CreateAsyncImgModelExecution(napi_env env,AsyncGetImageEmbeddingModelData * asyncModelData)314 bool ImageEmbeddingNapi::CreateAsyncImgModelExecution(napi_env env, AsyncGetImageEmbeddingModelData *asyncModelData)
315 {
316 AIP_HILOGI("Enter");
317 napi_value resourceName;
318 napi_status status = napi_create_string_utf8(env, "GetIamgeEmbeddingModel", NAPI_AUTO_LENGTH, &resourceName);
319 if (status != napi_ok) {
320 AIP_HILOGE(" napi_create_string_utf8 failed");
321 return false;
322 }
323
324 status = napi_create_async_work(env, nullptr, resourceName, GetImgEmbeddingModelExecutionCB,
325 GetImgEmbeddingModelCompleteCB, static_cast<void *>(asyncModelData), &asyncModelData->asyncWork);
326 if (status != napi_ok) {
327 AIP_HILOGE("napi_create_async_work failed");
328 return false;
329 }
330
331 status = napi_queue_async_work_with_qos(env, asyncModelData->asyncWork, napi_qos_default);
332 if (status != napi_ok) {
333 AIP_HILOGE("napi_queue_async_work_with_qos failed");
334 return false;
335 }
336 return true;
337 }
338
GetImgEmbeddingModelExecutionCB(napi_env env,void * data)339 void ImageEmbeddingNapi::GetImgEmbeddingModelExecutionCB(napi_env env, void *data)
340 {
341 AIP_HILOGD("Enter");
342 AsyncGetImageEmbeddingModelData *modelData = static_cast<AsyncGetImageEmbeddingModelData *>(data);
343 if (imageAipCoreManager_ == nullptr) {
344 AIP_HILOGE("pAipManager is nullptr");
345 return;
346 }
347 auto config = modelData->config;
348 int32_t result = imageAipCoreManager_->InitImageModel(config);
349 modelData->ret = result;
350 }
351
GetImgEmbeddingModelCompleteCB(napi_env env,napi_status status,void * data)352 void ImageEmbeddingNapi::GetImgEmbeddingModelCompleteCB(napi_env env, napi_status status, void *data)
353 {
354 AIP_HILOGD("Enter");
355 AsyncGetImageEmbeddingModelData *modelData = static_cast<AsyncGetImageEmbeddingModelData *>(data);
356 auto ret = modelData->ret;
357 napi_value result = nullptr;
358 if (ret != ERR_OK) {
359 if (ret == DEVICE_EXCEPTION) {
360 ThrowIntelligenceErrByPromise(env, DEVICE_EXCEPTION, "GetImgEmbeddingModelCompleteCB failed", result);
361 } else {
362 ThrowIntelligenceErrByPromise(env, INNER_ERROR, "GetImgEmbeddingModelCompleteCB failed", result);
363 }
364 napi_reject_deferred(env, modelData->deferred, result);
365 } else {
366 napi_value constructor = nullptr;
367 status = napi_get_reference_value(env, sConstructor_, &constructor);
368 if (status != napi_ok) {
369 AIP_HILOGE("napi_get_reference_value failed");
370 napi_get_undefined(env, &result);
371 delete modelData;
372 return;
373 }
374
375 status = napi_new_instance(env, constructor, 0, nullptr, &result);
376 if (status != napi_ok) {
377 AIP_HILOGE("napi_new_instance failed");
378 napi_get_undefined(env, &result);
379 delete modelData;
380 return;
381 }
382
383 status = napi_resolve_deferred(env, modelData->deferred, result);
384 if (status != napi_ok) {
385 AIP_HILOGE(" napi_resolve_deferred failed");
386 }
387 }
388
389 status = napi_delete_async_work(env, modelData->asyncWork);
390 if (status != napi_ok) {
391 AIP_HILOGE("napi_delete_async_work failed");
392 }
393 delete modelData;
394 }
395
GetEmbedding(napi_env env,napi_callback_info info)396 napi_value ImageEmbeddingNapi::GetEmbedding(napi_env env, napi_callback_info info)
397 {
398 AIP_HILOGE("Enter");
399 size_t argc = ARG_1;
400 napi_value args[ARG_1] = { nullptr };
401 napi_value jsThis = nullptr;
402
403 napi_status status = napi_get_cb_info(env, info, &argc, args, &jsThis, nullptr);
404 if (status != napi_ok) {
405 ThrowIntelligenceErr(env, INNER_ERROR, "napi_get_cb_info failed");
406 return nullptr;
407 }
408
409 if (!AipNapiUtils::ValidateArgsType(env, args, argc, EXPECTED_GET_ARG_TYPES)) {
410 ThrowIntelligenceErr(env, PARAM_EXCEPTION, "napi_get_cb_info failed");
411 return nullptr;
412 }
413
414 std::string strArg;
415 if (!AipNapiUtils::TransJsToStr(env, args[ARG_0], strArg)) {
416 ThrowIntelligenceErr(env, PARAM_EXCEPTION, "napi_get_cb_info failed");
417 return nullptr;
418 }
419
420 napi_value promise = nullptr;
421 napi_deferred deferred = nullptr;
422 status = napi_create_promise(env, &deferred, &promise);
423 if (status != napi_ok) {
424 ThrowIntelligenceErr(env, INNER_ERROR, "napi_create_promise failed");
425 return nullptr;
426 }
427
428 if (!GetEmbeddingAsyncExecution(env, deferred, strArg)) {
429 ThrowIntelligenceErr(env, INNER_ERROR, "GetEmbeddingAsyncExecution failed");
430 return nullptr;
431 }
432
433 return promise;
434 }
435
GetEmbeddingAsyncExecution(napi_env env,napi_deferred deferred,std::string strArg)436 bool ImageEmbeddingNapi::GetEmbeddingAsyncExecution(napi_env env, napi_deferred deferred, std::string strArg)
437 {
438 AIP_HILOGD("Enter");
439 auto imageCallbackData = new (std::nothrow) ImageCallbackData{
440 .asyncWork = nullptr,
441 .deferred = deferred,
442 .strArg = strArg,
443 };
444 if (imageCallbackData == nullptr) {
445 AIP_HILOGE("new imageCallbackData error.");
446 return false;
447 }
448
449 napi_value resourceName;
450 napi_status status = napi_create_string_utf8(env, "ImageGetEmbedding", NAPI_AUTO_LENGTH, &resourceName);
451 if (status != napi_ok) {
452 AIP_HILOGE("napi_create_string_utf8 failed");
453 delete imageCallbackData;
454 return false;
455 }
456
457 status = napi_create_async_work(env, nullptr, resourceName, GetEmbeddingExecuteCB, GetEmbeddingCompleteCB,
458 static_cast<void *>(imageCallbackData), &imageCallbackData->asyncWork);
459 if (status != napi_ok) {
460 AIP_HILOGE("napi_create_async_work failed");
461 delete imageCallbackData;
462 return false;
463 }
464
465 status = napi_queue_async_work_with_qos(env, imageCallbackData->asyncWork, napi_qos_default);
466 if (status != napi_ok) {
467 AIP_HILOGE("napi_queue_async_work_with_qos failed");
468 napi_delete_async_work(env, imageCallbackData->asyncWork);
469 delete imageCallbackData;
470 return false;
471 }
472 return true;
473 }
474
GetEmbeddingExecuteCB(napi_env env,void * data)475 void ImageEmbeddingNapi::GetEmbeddingExecuteCB(napi_env env, void *data)
476 {
477 AIP_HILOGD("Enter");
478 ImageCallbackData *imageCallbackData = static_cast<ImageCallbackData *>(data);
479 std::string strArg = imageCallbackData->strArg;
480 std::vector<float> result;
481 int32_t ret = imageAipCoreManager_->GetImageEmbedding(strArg, result);
482 imageCallbackData->dataRet = ret;
483 imageCallbackData->ret = result;
484 AIP_HILOGD("Exit");
485 }
486
GetEmbeddingCompleteCB(napi_env env,napi_status status,void * data)487 void ImageEmbeddingNapi::GetEmbeddingCompleteCB(napi_env env, napi_status status, void *data)
488 {
489 AIP_HILOGD("Enter");
490 ImageCallbackData *imageCallbackData = static_cast<ImageCallbackData *>(data);
491 napi_value value;
492 auto ret = imageCallbackData->ret;
493 auto dataRet = imageCallbackData->dataRet;
494
495 if (dataRet != ERR_OK) {
496 if (dataRet == DEVICE_EXCEPTION) {
497 ThrowIntelligenceErrByPromise(env, DEVICE_EXCEPTION, " GetEmbeddingCompleteCB failed", value);
498 } else {
499 ThrowIntelligenceErrByPromise(env, INNER_ERROR, "GetEmbeddingCompleteCB failed", value);
500 }
501 napi_reject_deferred(env, imageCallbackData->deferred, value);
502 } else {
503 status = napi_create_array(env, &value);
504 if (status != napi_ok) {
505 AIP_HILOGE("napi_create_array failed");
506 } else {
507 for (size_t i = 0; i < ret.size(); i++) {
508 napi_value jsDouble = nullptr;
509 AipNapiUtils::CreateDoubleData(env, static_cast<double>(ret[i]), &jsDouble);
510 napi_set_element(env, value, i, jsDouble);
511 }
512 status = napi_resolve_deferred(env, imageCallbackData->deferred, value);
513 if (status != napi_ok) {
514 AIP_HILOGE(" napi_resolve_deferred failed");
515 }
516 }
517 }
518
519 status = napi_delete_async_work(env, imageCallbackData->asyncWork);
520 if (status != napi_ok) {
521 AIP_HILOGE("napi_delete_async_work failed");
522 }
523 delete imageCallbackData;
524 }
525
LoadModel(napi_env env,napi_callback_info info)526 napi_value ImageEmbeddingNapi::LoadModel(napi_env env, napi_callback_info info)
527 {
528 AIP_HILOGD("Enter");
529 size_t argc = ARG_0;
530 napi_value args[ARG_1] = { nullptr };
531 napi_value jsThis = nullptr;
532
533 napi_status status = napi_get_cb_info(env, info, &argc, args, &jsThis, nullptr);
534 if (status != napi_ok) {
535 ThrowIntelligenceErr(env, INNER_ERROR, "napi_get_cb_info failed");
536 return nullptr;
537 }
538
539 if (argc != ARG_0) {
540 ThrowIntelligenceErr(env, PARAM_EXCEPTION, "param size error");
541 return nullptr;
542 }
543
544 napi_value promise = nullptr;
545 napi_deferred deferred = nullptr;
546 status = napi_create_promise(env, &deferred, &promise);
547 if (status != napi_ok) {
548 AIP_HILOGE("create promise failed");
549 ThrowIntelligenceErr(env, INNER_ERROR, "create promise failed");
550 return nullptr;
551 }
552
553 if (!LoadAsyncExecution(env, deferred)) {
554 ThrowIntelligenceErr(env, INNER_ERROR, "LoadAsyncExecution failed");
555 return nullptr;
556 }
557
558 AIP_HILOGD("Exit");
559 return promise;
560 }
561
LoadAsyncExecution(napi_env env,napi_deferred deferred)562 bool ImageEmbeddingNapi::LoadAsyncExecution(napi_env env, napi_deferred deferred)
563 {
564 AIP_HILOGD("Enter");
565 auto loadCallbackData = new (std::nothrow) LoadCallbackData{
566 .asyncWork = nullptr,
567 .deferred = deferred,
568 };
569 if (loadCallbackData == nullptr) {
570 AIP_HILOGE("new loadCallbackData error.");
571 return false;
572 }
573
574 napi_value resourceName;
575 napi_status status = napi_create_string_utf8(env, "imageLoad", NAPI_AUTO_LENGTH, &resourceName);
576 if (status != napi_ok) {
577 AIP_HILOGE("napi_create_string_utf8 failed");
578 delete loadCallbackData;
579 return false;
580 }
581
582 status = napi_create_async_work(env, nullptr, resourceName, LoadExecuteCB, LoadCompleteCB,
583 static_cast<void *>(loadCallbackData), &loadCallbackData->asyncWork);
584 if (status != napi_ok) {
585 AIP_HILOGE("napi_create_async_work failed");
586 delete loadCallbackData;
587 return false;
588 }
589
590 status = napi_queue_async_work_with_qos(env, loadCallbackData->asyncWork, napi_qos_default);
591 if (status != napi_ok) {
592 AIP_HILOGE("napi_queue_async_work_with_qos failed");
593 napi_delete_async_work(env, loadCallbackData->asyncWork);
594 delete loadCallbackData;
595 return false;
596 }
597 return true;
598 }
599
600
LoadExecuteCB(napi_env env,void * data)601 void ImageEmbeddingNapi::LoadExecuteCB(napi_env env, void *data)
602 {
603 AIP_HILOGD("Enter");
604 LoadCallbackData *loadCallbackData = static_cast<LoadCallbackData *>(data);
605 auto ret = imageAipCoreManager_->LoadImageModel();
606 loadCallbackData->ret = ret;
607 AIP_HILOGD("Exit");
608 }
609
LoadCompleteCB(napi_env env,napi_status status,void * data)610 void ImageEmbeddingNapi::LoadCompleteCB(napi_env env, napi_status status, void *data)
611 {
612 AIP_HILOGD("Enter");
613 LoadCallbackData *loadCallbackData = static_cast<LoadCallbackData *>(data);
614 napi_value value = nullptr;
615 auto ret = loadCallbackData->ret;
616 if (ret != ERR_OK) {
617 if (ret == DEVICE_EXCEPTION) {
618 ThrowIntelligenceErrByPromise(env, DEVICE_EXCEPTION, "LoadCompleteCB failed", value);
619 } else {
620 ThrowIntelligenceErrByPromise(env, INNER_ERROR, "LoadCompleteCB failed", value);
621 }
622 napi_reject_deferred(env, loadCallbackData->deferred, value);
623 } else {
624 status = napi_get_undefined(env, &value);
625 if (status != napi_ok) {
626 AIP_HILOGE(" napi_get_undefined failed");
627 }
628 status = napi_resolve_deferred(env, loadCallbackData->deferred, value);
629 if (status != napi_ok) {
630 AIP_HILOGE(" napi_resolve_deferred failed");
631 }
632 }
633
634 status = napi_delete_async_work(env, loadCallbackData->asyncWork);
635 if (status != napi_ok) {
636 AIP_HILOGE("napi_delete_async_work failed");
637 }
638 delete loadCallbackData;
639 }
640
ReleaseModel(napi_env env,napi_callback_info info)641 napi_value ImageEmbeddingNapi::ReleaseModel(napi_env env, napi_callback_info info)
642 {
643 AIP_HILOGD("Enter");
644 size_t argc = ARG_0;
645 napi_value args[ARG_1] = { nullptr };
646 napi_value jsThis = nullptr;
647
648 napi_status status = napi_get_cb_info(env, info, &argc, args, &jsThis, nullptr);
649 if (status != napi_ok) {
650 AIP_HILOGE("napi_get_cb_info failed");
651 ThrowIntelligenceErr(env, INNER_ERROR, "napi_get_cb_info failed");
652 return nullptr;
653 }
654
655 if (argc != ARG_0) {
656 ThrowIntelligenceErr(env, PARAM_EXCEPTION, "param size error");
657 return nullptr;
658 }
659
660 napi_value promise = nullptr;
661 napi_deferred deferred = nullptr;
662 status = napi_create_promise(env, &deferred, &promise);
663 if (status != napi_ok) {
664 ThrowIntelligenceErr(env, INNER_ERROR, "create promise failed");
665 return nullptr;
666 }
667
668 if (!ReleaseAsyncExecution(env, deferred)) {
669 ThrowIntelligenceErr(env, INNER_ERROR, "ReleaseAsyncExecution failed");
670 return nullptr;
671 }
672
673 AIP_HILOGD("Exit");
674 return promise;
675 }
676
ReleaseAsyncExecution(napi_env env,napi_deferred deferred)677 bool ImageEmbeddingNapi::ReleaseAsyncExecution(napi_env env, napi_deferred deferred)
678 {
679 AIP_HILOGD("Enter");
680 auto releaseCallbackData = new (std::nothrow) ReleaseCallbackData{
681 .asyncWork = nullptr,
682 .deferred = deferred,
683 };
684 if (releaseCallbackData == nullptr) {
685 AIP_HILOGE("new releaseCallbackData error.");
686 return false;
687 }
688
689 napi_value resourceName;
690 napi_status status = napi_create_string_utf8(env, "textLoad", NAPI_AUTO_LENGTH, &resourceName);
691 if (status != napi_ok) {
692 AIP_HILOGE("napi_create_string_utf8 failed");
693 delete releaseCallbackData;
694 return false;
695 }
696
697 status = napi_create_async_work(env, nullptr, resourceName, ReleaseExecuteCB, ReleaseCompleteCB,
698 static_cast<void *>(releaseCallbackData), &releaseCallbackData->asyncWork);
699 if (status != napi_ok) {
700 AIP_HILOGE("napi_create_async_work failed");
701 delete releaseCallbackData;
702 return false;
703 }
704
705 status = napi_queue_async_work_with_qos(env, releaseCallbackData->asyncWork, napi_qos_default);
706 if (status != napi_ok) {
707 AIP_HILOGE("napi_queue_async_work_with_qos failed");
708 napi_delete_async_work(env, releaseCallbackData->asyncWork);
709 delete releaseCallbackData;
710 return false;
711 }
712 return true;
713 }
ReleaseExecuteCB(napi_env env,void * data)714 void ImageEmbeddingNapi::ReleaseExecuteCB(napi_env env, void *data)
715 {
716 AIP_HILOGD("Enter");
717 ReleaseCallbackData *releaseCallbackData = static_cast<ReleaseCallbackData *>(data);
718 auto ret = imageAipCoreManager_->ReleaseImageModel();
719 releaseCallbackData->ret = ret;
720 AIP_HILOGD("Exit");
721 }
722
ReleaseCompleteCB(napi_env env,napi_status status,void * data)723 void ImageEmbeddingNapi::ReleaseCompleteCB(napi_env env, napi_status status, void *data)
724 {
725 AIP_HILOGD("Enter");
726 ReleaseCallbackData *releaseCallbackData = static_cast<ReleaseCallbackData *>(data);
727 napi_value value = nullptr;
728 auto ret = releaseCallbackData->ret;
729 if (ret != ERR_OK) {
730 if (ret == DEVICE_EXCEPTION) {
731 ThrowIntelligenceErrByPromise(env, DEVICE_EXCEPTION, "ReleaseCompleteCB failed", value);
732 } else {
733 ThrowIntelligenceErrByPromise(env, INNER_ERROR, "ReleaseCompleteCB failed", value);
734 }
735 napi_reject_deferred(env, releaseCallbackData->deferred, value);
736 } else {
737 status = napi_get_undefined(env, &value);
738 if (status != napi_ok) {
739 AIP_HILOGE(" napi_get_undefined failed");
740 }
741 status = napi_resolve_deferred(env, releaseCallbackData->deferred, value);
742 if (status != napi_ok) {
743 AIP_HILOGE(" napi_resolve_deferred failed");
744 }
745 }
746
747 status = napi_delete_async_work(env, releaseCallbackData->asyncWork);
748 if (status != napi_ok) {
749 AIP_HILOGE("napi_delete_async_work failed");
750 }
751 delete releaseCallbackData;
752 }
753 } // namespace DataIntelligence
754 } // namespace OHOS
755