• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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