• 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 const std::string AIP_MANAGER_PATH = "/system/lib64/platformsdk/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     imageAipCoreManager_ = nullptr;
83     delete imageAipCoreManager_;
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 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 AsyncGetImageEmbeddingModelData{
234         .asyncWork = nullptr,
235         .deferred = deferred,
236         .config = imgModelConfig,
237     };
238 
239     if (!CreateAsyncImgModelExecution(env, asyncGetImgEmbeddingModelData)) {
240         AIP_HILOGE("create AsyncTextModelExecution failed");
241         ThrowIntelligenceErr(env, INNER_ERROR, "create AsyncTextModelExecution failed");
242         delete asyncGetImgEmbeddingModelData;
243         return nullptr;
244     }
245 
246     return promise;
247 }
248 
ParseModelConfig(napi_env env,napi_value * args,size_t argc,ModelConfigData * modelConfig)249 bool ImageEmbeddingNapi::ParseModelConfig(napi_env env, napi_value *args, size_t argc, ModelConfigData *modelConfig)
250 {
251     AIP_HILOGI("Enter");
252     if (modelConfig == nullptr) {
253         AIP_HILOGE("The modelConfig is null");
254         return false;
255     }
256     if (!AipNapiUtils::CheckModelConfig(env, args[ARG_0])) {
257         AIP_HILOGE("The modelConfig is failed");
258         return false;
259     }
260 
261     napi_value version;
262     napi_value isNPUAvailable;
263     napi_value cachePath;
264     napi_status status = napi_get_named_property(env, args[ARG_0], "version", &version);
265     if (status != napi_ok) {
266         AIP_HILOGE("napi get version property failed");
267         return false;
268     }
269 
270     if (!AipNapiUtils::TransJsToInt32(env, version, modelConfig->versionValue)) {
271         AIP_HILOGE("Trans version failed");
272         return false;
273     }
274 
275     if (modelConfig->versionValue != BASIC_MODEL) {
276         AIP_HILOGE("The version value is invalid");
277         return false;
278     }
279 
280     status = napi_get_named_property(env, args[ARG_0], "isNpuAvailable", &isNPUAvailable);
281     if (status != napi_ok) {
282         AIP_HILOGE("napi get isNpuAvailable property failed");
283         return false;
284     }
285 
286     if (!AipNapiUtils::TransJsToBool(env, isNPUAvailable, modelConfig->isNPUAvailableValue)) {
287         AIP_HILOGE("Trans isNPUAvailable failed");
288         return false;
289     }
290 
291     if (modelConfig->isNPUAvailableValue) {
292         status = napi_get_named_property(env, args[ARG_0], "cachePath", &cachePath);
293         if (status != napi_ok) {
294             AIP_HILOGE("napi get cachePath property failed");
295             return false;
296         }
297 
298         if (!AipNapiUtils::TransJsToStr(env, cachePath, modelConfig->cachePathValue)) {
299             AIP_HILOGE("Trans cachePath failed");
300             return false;
301         }
302     } else {
303         modelConfig->cachePathValue = "";
304     }
305     return true;
306 }
307 
308 
CreateAsyncImgModelExecution(napi_env env,AsyncGetImageEmbeddingModelData * asyncModelData)309 bool ImageEmbeddingNapi::CreateAsyncImgModelExecution(napi_env env, AsyncGetImageEmbeddingModelData *asyncModelData)
310 {
311     AIP_HILOGI("Enter");
312     napi_value resourceName;
313     napi_status status = napi_create_string_utf8(env, "GetIamgeEmbeddingModel", NAPI_AUTO_LENGTH, &resourceName);
314     if (status != napi_ok) {
315         AIP_HILOGE(" napi_create_string_utf8 failed");
316         return false;
317     }
318 
319     status = napi_create_async_work(env, nullptr, resourceName, GetImgEmbeddingModelExecutionCB,
320         GetImgEmbeddingModelCompleteCB, static_cast<void *>(asyncModelData), &asyncModelData->asyncWork);
321     if (status != napi_ok) {
322         AIP_HILOGE("napi_create_async_work failed");
323         return false;
324     }
325 
326     status = napi_queue_async_work_with_qos(env, asyncModelData->asyncWork, napi_qos_default);
327     if (status != napi_ok) {
328         AIP_HILOGE("napi_queue_async_work_with_qos failed");
329         return false;
330     }
331     return true;
332 }
333 
GetImgEmbeddingModelExecutionCB(napi_env env,void * data)334 void ImageEmbeddingNapi::GetImgEmbeddingModelExecutionCB(napi_env env, void *data)
335 {
336     AIP_HILOGD("Enter");
337     AsyncGetImageEmbeddingModelData *modelData = static_cast<AsyncGetImageEmbeddingModelData *>(data);
338     if (imageAipCoreManager_ == nullptr) {
339         AIP_HILOGE("pAipManager is nullptr");
340         return;
341     }
342     auto config = modelData->config;
343     int32_t result = imageAipCoreManager_->InitImageModel(config);
344     modelData->ret = result;
345 }
346 
GetImgEmbeddingModelCompleteCB(napi_env env,napi_status status,void * data)347 void ImageEmbeddingNapi::GetImgEmbeddingModelCompleteCB(napi_env env, napi_status status, void *data)
348 {
349     AIP_HILOGD("Enter");
350     AsyncGetImageEmbeddingModelData *modelData = static_cast<AsyncGetImageEmbeddingModelData *>(data);
351     auto ret = modelData->ret;
352     napi_value result = nullptr;
353     if (ret != ERR_OK) {
354         if (ret == DEVICE_EXCEPTION) {
355             ThrowIntelligenceErrByPromise(env, DEVICE_EXCEPTION, "GetImgEmbeddingModelCompleteCB failed", result);
356         } else {
357             ThrowIntelligenceErrByPromise(env, INNER_ERROR, "GetImgEmbeddingModelCompleteCB failed", result);
358         }
359         napi_reject_deferred(env, modelData->deferred, result);
360     } else {
361         napi_value constructor = nullptr;
362         status = napi_get_reference_value(env, sConstructor_, &constructor);
363         if (status != napi_ok) {
364             AIP_HILOGE("napi_get_reference_value failed");
365             napi_get_undefined(env, &result);
366             delete modelData;
367             return;
368         }
369 
370         status = napi_new_instance(env, constructor, 0, nullptr, &result);
371         if (status != napi_ok) {
372             AIP_HILOGE("napi_new_instance failed");
373             napi_get_undefined(env, &result);
374             return;
375         }
376 
377         status = napi_resolve_deferred(env, modelData->deferred, result);
378         if (status != napi_ok) {
379             AIP_HILOGE(" napi_resolve_deferred failed");
380         }
381     }
382 
383     status = napi_delete_async_work(env, modelData->asyncWork);
384     if (status != napi_ok) {
385         AIP_HILOGE("napi_delete_async_work failed");
386     }
387     delete modelData;
388 }
389 
GetEmbedding(napi_env env,napi_callback_info info)390 napi_value ImageEmbeddingNapi::GetEmbedding(napi_env env, napi_callback_info info)
391 {
392     AIP_HILOGE("Enter");
393     size_t argc = ARG_1;
394     napi_value args[ARG_1] = { nullptr };
395     napi_value jsThis = nullptr;
396 
397     napi_status status = napi_get_cb_info(env, info, &argc, args, &jsThis, nullptr);
398     if (status != napi_ok) {
399         ThrowIntelligenceErr(env, INNER_ERROR, "napi_get_cb_info failed");
400         return nullptr;
401     }
402 
403     if (!AipNapiUtils::ValidateArgsType(env, args, argc, EXPECTED_GET_ARG_TYPES)) {
404         ThrowIntelligenceErr(env, PARAM_EXCEPTION, "napi_get_cb_info failed");
405         return nullptr;
406     }
407 
408     std::string strArg;
409     if (!AipNapiUtils::TransJsToStr(env, args[ARG_0], strArg)) {
410         ThrowIntelligenceErr(env, PARAM_EXCEPTION, "napi_get_cb_info failed");
411         return nullptr;
412     }
413 
414     napi_value promise = nullptr;
415     napi_deferred deferred = nullptr;
416     status = napi_create_promise(env, &deferred, &promise);
417     if (status != napi_ok) {
418         ThrowIntelligenceErr(env, INNER_ERROR, "napi_create_promise failed");
419         return nullptr;
420     }
421 
422     if (!GetEmbeddingAsyncExecution(env, deferred, strArg)) {
423         ThrowIntelligenceErr(env, INNER_ERROR, "GetEmbeddingAsyncExecution failed");
424         return nullptr;
425     }
426 
427     return promise;
428 }
429 
GetEmbeddingAsyncExecution(napi_env env,napi_deferred deferred,std::string strArg)430 bool ImageEmbeddingNapi::GetEmbeddingAsyncExecution(napi_env env, napi_deferred deferred, std::string strArg)
431 {
432     AIP_HILOGD("Enter");
433     auto imageCallbackData = new ImageCallbackData{
434         .asyncWork = nullptr,
435         .deferred = deferred,
436         .strArg = strArg,
437     };
438 
439     napi_value resourceName;
440     napi_status status = napi_create_string_utf8(env, "ImageGetEmbedding", NAPI_AUTO_LENGTH, &resourceName);
441     if (status != napi_ok) {
442         AIP_HILOGE("napi_create_string_utf8 failed");
443         delete imageCallbackData;
444         return false;
445     }
446 
447     status = napi_create_async_work(env, nullptr, resourceName, GetEmbeddingExecuteCB, GetEmbeddingCompleteCB,
448         static_cast<void *>(imageCallbackData), &imageCallbackData->asyncWork);
449     if (status != napi_ok) {
450         AIP_HILOGE("napi_create_async_work failed");
451         delete imageCallbackData;
452         return false;
453     }
454 
455     status = napi_queue_async_work_with_qos(env, imageCallbackData->asyncWork, napi_qos_default);
456     if (status != napi_ok) {
457         AIP_HILOGE("napi_queue_async_work_with_qos failed");
458         napi_delete_async_work(env, imageCallbackData->asyncWork);
459         delete imageCallbackData;
460         return false;
461     }
462     return true;
463 }
464 
GetEmbeddingExecuteCB(napi_env env,void * data)465 void ImageEmbeddingNapi::GetEmbeddingExecuteCB(napi_env env, void *data)
466 {
467     AIP_HILOGD("Enter");
468     ImageCallbackData *imageCallbackData = static_cast<ImageCallbackData *>(data);
469     std::string strArg = imageCallbackData->strArg;
470     std::vector<float> result;
471     int32_t ret = imageAipCoreManager_->GetImageEmbedding(strArg, result);
472     imageCallbackData->dataRet = ret;
473     imageCallbackData->ret = result;
474     AIP_HILOGD("Exit");
475 }
476 
GetEmbeddingCompleteCB(napi_env env,napi_status status,void * data)477 void ImageEmbeddingNapi::GetEmbeddingCompleteCB(napi_env env, napi_status status, void *data)
478 {
479     AIP_HILOGD("Enter");
480     ImageCallbackData *imageCallbackData = static_cast<ImageCallbackData *>(data);
481     napi_value value;
482     auto ret = imageCallbackData->ret;
483     auto dataRet = imageCallbackData->dataRet;
484 
485     if (dataRet != ERR_OK) {
486         if (dataRet == DEVICE_EXCEPTION) {
487             ThrowIntelligenceErrByPromise(env, DEVICE_EXCEPTION, " GetEmbeddingCompleteCB failed", value);
488         } else {
489             ThrowIntelligenceErrByPromise(env, INNER_ERROR, "GetEmbeddingCompleteCB  failed", value);
490         }
491         napi_reject_deferred(env, imageCallbackData->deferred, value);
492     } else {
493         status = napi_create_array(env, &value);
494         if (status != napi_ok) {
495             AIP_HILOGE("napi_create_array failed");
496         } else {
497             for (size_t i = 0; i < ret.size(); i++) {
498                 napi_value jsDouble = nullptr;
499                 AipNapiUtils::CreateDoubleData(env, static_cast<double>(ret[i]), &jsDouble);
500                 napi_set_element(env, value, i, jsDouble);
501             }
502             status = napi_resolve_deferred(env, imageCallbackData->deferred, value);
503             if (status != napi_ok) {
504                 AIP_HILOGE(" napi_resolve_deferred failed");
505             }
506         }
507     }
508 
509     status = napi_delete_async_work(env, imageCallbackData->asyncWork);
510     if (status != napi_ok) {
511         AIP_HILOGE("napi_delete_async_work failed");
512     }
513     delete imageCallbackData;
514 }
515 
LoadModel(napi_env env,napi_callback_info info)516 napi_value ImageEmbeddingNapi::LoadModel(napi_env env, napi_callback_info info)
517 {
518     AIP_HILOGD("Enter");
519     size_t argc = ARG_0;
520     napi_value args[ARG_1] = { nullptr };
521     napi_value jsThis = nullptr;
522 
523     napi_status status = napi_get_cb_info(env, info, &argc, args, &jsThis, nullptr);
524     if (status != napi_ok) {
525         ThrowIntelligenceErr(env, INNER_ERROR, "napi_get_cb_info failed");
526         return nullptr;
527     }
528 
529     if (argc != ARG_0) {
530         ThrowIntelligenceErr(env, PARAM_EXCEPTION, "param size error");
531         return nullptr;
532     }
533 
534     napi_value promise = nullptr;
535     napi_deferred deferred = nullptr;
536     status = napi_create_promise(env, &deferred, &promise);
537     if (status != napi_ok) {
538         AIP_HILOGE("create promise failed");
539         ThrowIntelligenceErr(env, INNER_ERROR, "create promise failed");
540         return nullptr;
541     }
542 
543     if (!LoadAsyncExecution(env, deferred)) {
544         ThrowIntelligenceErr(env, INNER_ERROR, "LoadAsyncExecution failed");
545         return nullptr;
546     }
547 
548     AIP_HILOGD("Exit");
549     return promise;
550 }
551 
LoadAsyncExecution(napi_env env,napi_deferred deferred)552 bool ImageEmbeddingNapi::LoadAsyncExecution(napi_env env, napi_deferred deferred)
553 {
554     AIP_HILOGD("Enter");
555     auto loadCallbackData = new LoadCallbackData{
556         .asyncWork = nullptr,
557         .deferred = deferred,
558     };
559 
560     napi_value resourceName;
561     napi_status status = napi_create_string_utf8(env, "imageLoad", NAPI_AUTO_LENGTH, &resourceName);
562     if (status != napi_ok) {
563         AIP_HILOGE("napi_create_string_utf8 failed");
564         delete loadCallbackData;
565         return false;
566     }
567 
568     status = napi_create_async_work(env, nullptr, resourceName, LoadExecuteCB, LoadCompleteCB,
569         static_cast<void *>(loadCallbackData), &loadCallbackData->asyncWork);
570     if (status != napi_ok) {
571         AIP_HILOGE("napi_create_async_work failed");
572         delete loadCallbackData;
573         return false;
574     }
575 
576     status = napi_queue_async_work_with_qos(env, loadCallbackData->asyncWork, napi_qos_default);
577     if (status != napi_ok) {
578         AIP_HILOGE("napi_queue_async_work_with_qos failed");
579         napi_delete_async_work(env, loadCallbackData->asyncWork);
580         delete loadCallbackData;
581         return false;
582     }
583     return true;
584 }
585 
586 
LoadExecuteCB(napi_env env,void * data)587 void ImageEmbeddingNapi::LoadExecuteCB(napi_env env, void *data)
588 {
589     AIP_HILOGD("Enter");
590     LoadCallbackData *loadCallbackData = static_cast<LoadCallbackData *>(data);
591     auto ret = imageAipCoreManager_->LoadImageModel();
592     loadCallbackData->ret = ret;
593     AIP_HILOGD("Exit");
594 }
595 
LoadCompleteCB(napi_env env,napi_status status,void * data)596 void ImageEmbeddingNapi::LoadCompleteCB(napi_env env, napi_status status, void *data)
597 {
598     AIP_HILOGD("Enter");
599     LoadCallbackData *loadCallbackData = static_cast<LoadCallbackData *>(data);
600     napi_value value = nullptr;
601     auto ret = loadCallbackData->ret;
602     if (ret != ERR_OK) {
603         if (ret == DEVICE_EXCEPTION) {
604             ThrowIntelligenceErrByPromise(env, DEVICE_EXCEPTION, "LoadCompleteCB failed", value);
605         } else {
606             ThrowIntelligenceErrByPromise(env, INNER_ERROR, "LoadCompleteCB failed", value);
607         }
608         napi_reject_deferred(env, loadCallbackData->deferred, value);
609     } else {
610         status = napi_get_undefined(env, &value);
611         if (status != napi_ok) {
612             AIP_HILOGE(" napi_get_undefined failed");
613         }
614         status = napi_resolve_deferred(env, loadCallbackData->deferred, value);
615         if (status != napi_ok) {
616             AIP_HILOGE(" napi_resolve_deferred failed");
617         }
618     }
619 
620     status = napi_delete_async_work(env, loadCallbackData->asyncWork);
621     if (status != napi_ok) {
622         AIP_HILOGE("napi_delete_async_work failed");
623     }
624     delete loadCallbackData;
625 }
626 
ReleaseModel(napi_env env,napi_callback_info info)627 napi_value ImageEmbeddingNapi::ReleaseModel(napi_env env, napi_callback_info info)
628 {
629     AIP_HILOGD("Enter");
630     size_t argc = ARG_0;
631     napi_value args[ARG_1] = { nullptr };
632     napi_value jsThis = nullptr;
633 
634     napi_status status = napi_get_cb_info(env, info, &argc, args, &jsThis, nullptr);
635     if (status != napi_ok) {
636         AIP_HILOGE("napi_get_cb_info failed");
637         ThrowIntelligenceErr(env, INNER_ERROR, "napi_get_cb_info failed");
638         return nullptr;
639     }
640 
641     if (argc != ARG_0) {
642         ThrowIntelligenceErr(env, PARAM_EXCEPTION, "param size error");
643         return nullptr;
644     }
645 
646     napi_value promise = nullptr;
647     napi_deferred deferred = nullptr;
648     status = napi_create_promise(env, &deferred, &promise);
649     if (status != napi_ok) {
650         ThrowIntelligenceErr(env, INNER_ERROR, "create promise failed");
651         return nullptr;
652     }
653 
654     if (!ReleaseAsyncExecution(env, deferred)) {
655         ThrowIntelligenceErr(env, INNER_ERROR, "ReleaseAsyncExecution failed");
656         return nullptr;
657     }
658 
659     AIP_HILOGD("Exit");
660     return promise;
661 }
662 
ReleaseAsyncExecution(napi_env env,napi_deferred deferred)663 bool ImageEmbeddingNapi::ReleaseAsyncExecution(napi_env env, napi_deferred deferred)
664 {
665     AIP_HILOGD("Enter");
666     auto releaseCallbackData = new ReleaseCallbackData{
667         .asyncWork = nullptr,
668         .deferred = deferred,
669     };
670 
671     napi_value resourceName;
672     napi_status status = napi_create_string_utf8(env, "textLoad", NAPI_AUTO_LENGTH, &resourceName);
673     if (status != napi_ok) {
674         AIP_HILOGE("napi_create_string_utf8 failed");
675         delete releaseCallbackData;
676         return false;
677     }
678 
679     status = napi_create_async_work(env, nullptr, resourceName, ReleaseExecuteCB, ReleaseCompleteCB,
680         static_cast<void *>(releaseCallbackData), &releaseCallbackData->asyncWork);
681     if (status != napi_ok) {
682         AIP_HILOGE("napi_create_async_work failed");
683         delete releaseCallbackData;
684         return false;
685     }
686 
687     status = napi_queue_async_work_with_qos(env, releaseCallbackData->asyncWork, napi_qos_default);
688     if (status != napi_ok) {
689         AIP_HILOGE("napi_queue_async_work_with_qos failed");
690         napi_delete_async_work(env, releaseCallbackData->asyncWork);
691         delete releaseCallbackData;
692         return false;
693     }
694     return true;
695 }
ReleaseExecuteCB(napi_env env,void * data)696 void ImageEmbeddingNapi::ReleaseExecuteCB(napi_env env, void *data)
697 {
698     AIP_HILOGD("Enter");
699     ReleaseCallbackData *releaseCallbackData = static_cast<ReleaseCallbackData *>(data);
700     auto ret = imageAipCoreManager_->ReleaseImageModel();
701     releaseCallbackData->ret = ret;
702     AIP_HILOGD("Exit");
703 }
704 
ReleaseCompleteCB(napi_env env,napi_status status,void * data)705 void ImageEmbeddingNapi::ReleaseCompleteCB(napi_env env, napi_status status, void *data)
706 {
707     AIP_HILOGD("Enter");
708     ReleaseCallbackData *releaseCallbackData = static_cast<ReleaseCallbackData *>(data);
709     napi_value value = nullptr;
710     auto ret = releaseCallbackData->ret;
711     if (ret != ERR_OK) {
712         if (ret == DEVICE_EXCEPTION) {
713             ThrowIntelligenceErrByPromise(env, DEVICE_EXCEPTION, "ReleaseCompleteCB failed", value);
714         } else {
715             ThrowIntelligenceErrByPromise(env, INNER_ERROR, "ReleaseCompleteCB failed", value);
716         }
717         napi_reject_deferred(env, releaseCallbackData->deferred, value);
718     } else {
719         status = napi_get_undefined(env, &value);
720         if (status != napi_ok) {
721             AIP_HILOGE(" napi_get_undefined failed");
722         }
723         status = napi_resolve_deferred(env, releaseCallbackData->deferred, value);
724         if (status != napi_ok) {
725             AIP_HILOGE(" napi_resolve_deferred failed");
726         }
727     }
728 
729     status = napi_delete_async_work(env, releaseCallbackData->asyncWork);
730     if (status != napi_ok) {
731         AIP_HILOGE("napi_delete_async_work failed");
732     }
733     delete releaseCallbackData;
734 }
735 } // namespace DataIntelligence
736 } // namespace OHOS
737