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