1 /*
2 * Copyright (C) 2024 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 #define MLOG_TAG "FetchResultNapi"
16
17 #include "sendable_fetch_file_result_napi.h"
18
19 #include "album_napi.h"
20 #include "hitrace_meter.h"
21 #include "medialibrary_client_errno.h"
22 #include "medialibrary_napi_log.h"
23 #include "medialibrary_napi_utils.h"
24 #include "medialibrary_tracer.h"
25 #include "sendable_photo_album_napi.h"
26 #include "sendable_medialibrary_napi_utils.h"
27 #include "smart_album_napi.h"
28 #include "media_file_utils.h"
29
30 using OHOS::HiviewDFX::HiLog;
31 using OHOS::HiviewDFX::HiLogLabel;
32 using namespace std;
33
34 namespace OHOS {
35 namespace Media {
36 thread_local napi_ref SendableFetchFileResultNapi::photoAccessHelperConstructor_ = nullptr;
37
SendableFetchFileResultNapi()38 SendableFetchFileResultNapi::SendableFetchFileResultNapi()
39 : env_(nullptr) {}
40
~SendableFetchFileResultNapi()41 SendableFetchFileResultNapi::~SendableFetchFileResultNapi()
42 {
43 propertyPtr = nullptr;
44 }
45
FetchFileResultNapiDestructor(napi_env env,void * nativeObject,void * finalize_hint)46 void SendableFetchFileResultNapi::FetchFileResultNapiDestructor(napi_env env, void *nativeObject, void *finalize_hint)
47 {
48 SendableFetchFileResultNapi *fetchFileResultObj = reinterpret_cast<SendableFetchFileResultNapi*>(nativeObject);
49 if (fetchFileResultObj != nullptr) {
50 delete fetchFileResultObj;
51 fetchFileResultObj = nullptr;
52 }
53 }
54
GetFetchResult(unique_ptr<SendableFetchFileResultNapi> & obj)55 void SendableFetchFileResultNapi::GetFetchResult(unique_ptr<SendableFetchFileResultNapi> &obj)
56 {
57 switch (sFetchResType_) {
58 case FetchResType::TYPE_FILE: {
59 auto fileResult = make_shared<FetchResult<FileAsset>>(move(sFetchFileResult_->GetDataShareResultSet()));
60 obj->propertyPtr->fetchFileResult_ = fileResult;
61 obj->propertyPtr->fetchFileResult_->SetInfo(sFetchFileResult_);
62 obj->propertyPtr->fetchFileResult_->SetUserId(sFetchFileResult_->GetUserId());
63 break;
64 }
65 case FetchResType::TYPE_ALBUM: {
66 auto albumResult = make_shared<FetchResult<AlbumAsset>>(move(sFetchAlbumResult_->GetDataShareResultSet()));
67 obj->propertyPtr->fetchAlbumResult_ = albumResult;
68 obj->propertyPtr->fetchAlbumResult_->SetInfo(sFetchAlbumResult_);
69 obj->propertyPtr->fetchAlbumResult_->SetUserId(sFetchAlbumResult_->GetUserId());
70 break;
71 }
72 case FetchResType::TYPE_PHOTOALBUM: {
73 auto photoAlbumResult =
74 make_shared<FetchResult<PhotoAlbum>>(move(sFetchPhotoAlbumResult_->GetDataShareResultSet()));
75 obj->propertyPtr->fetchPhotoAlbumResult_ = photoAlbumResult;
76 obj->propertyPtr->fetchPhotoAlbumResult_->SetInfo(sFetchPhotoAlbumResult_);
77 obj->propertyPtr->fetchPhotoAlbumResult_->SetUserId(sFetchPhotoAlbumResult_->GetUserId());
78 break;
79 }
80 case FetchResType::TYPE_SMARTALBUM: {
81 auto smartResult =
82 make_shared<FetchResult<SmartAlbumAsset>>(move(sFetchSmartAlbumResult_->GetDataShareResultSet()));
83 obj->propertyPtr->fetchSmartAlbumResult_ = smartResult;
84 obj->propertyPtr->fetchSmartAlbumResult_->SetInfo(sFetchSmartAlbumResult_);
85 break;
86 }
87 default:
88 NAPI_ERR_LOG("unsupported FetchResType");
89 break;
90 }
91 }
92
93 // Constructor callback
FetchFileResultNapiConstructor(napi_env env,napi_callback_info info)94 napi_value SendableFetchFileResultNapi::FetchFileResultNapiConstructor(napi_env env, napi_callback_info info)
95 {
96 MediaLibraryTracer tracer;
97 tracer.Start("FetchFileResultNapiConstructor");
98
99 napi_status status;
100 napi_value result = nullptr;
101 napi_value thisVar = nullptr;
102
103 napi_get_undefined(env, &result);
104 GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
105 if (status != napi_ok || thisVar == nullptr) {
106 NAPI_ERR_LOG("Get Js obj failed, status: %{public}d, (thisVar == nullptr) = %{public}d",
107 status, (thisVar == nullptr));
108 return result;
109 }
110
111 unique_ptr<SendableFetchFileResultNapi> obj = make_unique<SendableFetchFileResultNapi>();
112 if (obj == nullptr) {
113 NAPI_ERR_LOG("Get SendableFetchFileResultNapi failed");
114 return result;
115 }
116 obj->env_ = env;
117 obj->propertyPtr = make_shared<SendableFetchResultProperty>();
118 GetFetchResult(obj);
119 obj->propertyPtr->fetchResType_ = sFetchResType_;
120 status = napi_wrap_sendable(env, thisVar, reinterpret_cast<void *>(obj.get()),
121 SendableFetchFileResultNapi::FetchFileResultNapiDestructor, nullptr);
122 if (status == napi_ok) {
123 obj.release();
124 return thisVar;
125 } else {
126 NAPI_ERR_LOG("Failure wrapping js to native napi, status: %{public}d", status);
127 }
128 return result;
129 }
130
GetFetchResType()131 FetchResType SendableFetchFileResultNapi::GetFetchResType()
132 {
133 return propertyPtr->fetchResType_;
134 }
135
SolveConstructorRef(unique_ptr<FetchResult<FileAsset>> & fileResult,napi_ref & constructorRef)136 void SendableFetchFileResultNapi::SolveConstructorRef(unique_ptr<FetchResult<FileAsset>> &fileResult,
137 napi_ref &constructorRef)
138 {
139 switch (fileResult->GetResultNapiType()) {
140 case ResultNapiType::TYPE_PHOTOACCESS_HELPER: {
141 constructorRef = photoAccessHelperConstructor_;
142 break;
143 }
144 default:
145 NAPI_ERR_LOG("Invalid result napi type: %{public}d", static_cast<int>(fileResult->GetResultNapiType()));
146 constructorRef = nullptr;
147 break;
148 }
149 }
150
SolveConstructorRef(unique_ptr<FetchResult<AlbumAsset>> & fileResult,napi_ref & constructorRef)151 void SendableFetchFileResultNapi::SolveConstructorRef(unique_ptr<FetchResult<AlbumAsset>> &fileResult,
152 napi_ref &constructorRef)
153 {
154 switch (fileResult->GetResultNapiType()) {
155 case ResultNapiType::TYPE_PHOTOACCESS_HELPER: {
156 constructorRef = photoAccessHelperConstructor_;
157 break;
158 }
159 default:
160 NAPI_ERR_LOG("Invalid result napi type: %{public}d", static_cast<int>(fileResult->GetResultNapiType()));
161 constructorRef = nullptr;
162 break;
163 }
164 }
165
SolveConstructorRef(unique_ptr<FetchResult<SmartAlbumAsset>> & fileResult,napi_ref & constructorRef)166 void SendableFetchFileResultNapi::SolveConstructorRef(unique_ptr<FetchResult<SmartAlbumAsset>> &fileResult,
167 napi_ref &constructorRef)
168 {
169 switch (fileResult->GetResultNapiType()) {
170 case ResultNapiType::TYPE_PHOTOACCESS_HELPER: {
171 constructorRef = photoAccessHelperConstructor_;
172 break;
173 }
174 default:
175 NAPI_ERR_LOG("Invalid result napi type: %{public}d", static_cast<int>(fileResult->GetResultNapiType()));
176 constructorRef = nullptr;
177 break;
178 }
179 }
180
SolveConstructorRef(unique_ptr<FetchResult<PhotoAlbum>> & fileResult,napi_ref & constructorRef)181 void SendableFetchFileResultNapi::SolveConstructorRef(unique_ptr<FetchResult<PhotoAlbum>> &fileResult,
182 napi_ref &constructorRef)
183 {
184 switch (fileResult->GetResultNapiType()) {
185 case ResultNapiType::TYPE_PHOTOACCESS_HELPER: {
186 constructorRef = photoAccessHelperConstructor_;
187 break;
188 }
189 default:
190 NAPI_ERR_LOG("Invalid result napi type: %{public}d", static_cast<int>(fileResult->GetResultNapiType()));
191 constructorRef = nullptr;
192 break;
193 }
194 }
195
CreateFetchFileResult(napi_env env,unique_ptr<FetchResult<FileAsset>> fileResult)196 napi_value SendableFetchFileResultNapi::CreateFetchFileResult(napi_env env,
197 unique_ptr<FetchResult<FileAsset>> fileResult)
198 {
199 if (photoAccessHelperConstructor_ == nullptr) {
200 napi_value exports = nullptr;
201 napi_create_object(env, &exports);
202 SendableFetchFileResultNapi::PhotoAccessHelperInit(env, exports);
203 }
204
205 MediaLibraryTracer tracer;
206 tracer.Start("CreateFetchFileResult");
207 napi_value constructor;
208 napi_ref constructorRef;
209
210 SendableFetchFileResultNapi::SolveConstructorRef(fileResult, constructorRef);
211 NAPI_CALL(env, napi_get_reference_value(env, constructorRef, &constructor));
212 sFetchResType_ = fileResult->GetFetchResType();
213 sFetchFileResult_ = move(fileResult);
214 napi_value result = nullptr;
215 NAPI_CALL(env, napi_new_instance(env, constructor, 0, nullptr, &result));
216 sFetchFileResult_ = nullptr;
217 return result;
218 }
219
CreateFetchFileResult(napi_env env,unique_ptr<FetchResult<AlbumAsset>> fileResult)220 napi_value SendableFetchFileResultNapi::CreateFetchFileResult(napi_env env,
221 unique_ptr<FetchResult<AlbumAsset>> fileResult)
222 {
223 if (photoAccessHelperConstructor_ == nullptr) {
224 napi_value exports = nullptr;
225 napi_create_object(env, &exports);
226 SendableFetchFileResultNapi::PhotoAccessHelperInit(env, exports);
227 }
228
229 MediaLibraryTracer tracer;
230 tracer.Start("CreateFetchFileResult");
231 napi_value constructor;
232 napi_ref constructorRef;
233 SendableFetchFileResultNapi::SolveConstructorRef(fileResult, constructorRef);
234 NAPI_CALL(env, napi_get_reference_value(env, constructorRef, &constructor));
235 sFetchResType_ = fileResult->GetFetchResType();
236 sFetchAlbumResult_ = move(fileResult);
237 napi_value result = nullptr;
238 NAPI_CALL(env, napi_new_instance(env, constructor, 0, nullptr, &result));
239 sFetchAlbumResult_ = nullptr;
240 return result;
241 }
242
CreateFetchFileResult(napi_env env,unique_ptr<FetchResult<PhotoAlbum>> fileResult)243 napi_value SendableFetchFileResultNapi::CreateFetchFileResult(napi_env env,
244 unique_ptr<FetchResult<PhotoAlbum>> fileResult)
245 {
246 if (photoAccessHelperConstructor_ == nullptr) {
247 napi_value exports = nullptr;
248 napi_create_object(env, &exports);
249 SendableFetchFileResultNapi::PhotoAccessHelperInit(env, exports);
250 }
251
252 MediaLibraryTracer tracer;
253 tracer.Start("CreateFetchFileResult");
254 napi_value constructor;
255 napi_ref constructorRef;
256 SendableFetchFileResultNapi::SolveConstructorRef(fileResult, constructorRef);
257 NAPI_CALL(env, napi_get_reference_value(env, constructorRef, &constructor));
258 sFetchResType_ = fileResult->GetFetchResType();
259 sFetchPhotoAlbumResult_ = move(fileResult);
260 napi_value result = nullptr;
261 NAPI_CALL(env, napi_new_instance(env, constructor, 0, nullptr, &result));
262 sFetchPhotoAlbumResult_ = nullptr;
263 return result;
264 }
265
CreateFetchFileResult(napi_env env,unique_ptr<FetchResult<SmartAlbumAsset>> fileResult)266 napi_value SendableFetchFileResultNapi::CreateFetchFileResult(napi_env env,
267 unique_ptr<FetchResult<SmartAlbumAsset>> fileResult)
268 {
269 if (photoAccessHelperConstructor_ == nullptr) {
270 napi_value exports = nullptr;
271 napi_create_object(env, &exports);
272 SendableFetchFileResultNapi::PhotoAccessHelperInit(env, exports);
273 }
274
275 MediaLibraryTracer tracer;
276 tracer.Start("CreateFetchFileResult");
277 napi_value constructor;
278 napi_ref constructorRef;
279 SendableFetchFileResultNapi::SolveConstructorRef(fileResult, constructorRef);
280 NAPI_CALL(env, napi_get_reference_value(env, constructorRef, &constructor));
281 sFetchResType_ = fileResult->GetFetchResType();
282 sFetchSmartAlbumResult_ = move(fileResult);
283 napi_value result = nullptr;
284 NAPI_CALL(env, napi_new_instance(env, constructor, 0, nullptr, &result));
285 sFetchSmartAlbumResult_ = nullptr;
286 return result;
287 }
288
GetFetchFileResult() const289 std::shared_ptr<FetchResult<FileAsset>> SendableFetchFileResultNapi::GetFetchFileResult() const
290 {
291 return propertyPtr->fetchFileResult_;
292 }
293
PhotoAccessHelperInit(napi_env env,napi_value exports)294 napi_value SendableFetchFileResultNapi::PhotoAccessHelperInit(napi_env env, napi_value exports)
295 {
296 napi_value ctorObj;
297 napi_property_descriptor props[] = {
298 DECLARE_NAPI_FUNCTION("getCount", JSGetCount),
299 DECLARE_NAPI_FUNCTION("isAfterLast", JSIsAfterLast),
300 DECLARE_NAPI_FUNCTION("getFirstObject", JSGetFirstObject),
301 DECLARE_NAPI_FUNCTION("getNextObject", JSGetNextObject),
302 DECLARE_NAPI_FUNCTION("getAllObjects", JSGetAllObject),
303 DECLARE_NAPI_FUNCTION("getLastObject", JSGetLastObject),
304 DECLARE_NAPI_FUNCTION("getObjectByPosition", JSGetPositionObject),
305 DECLARE_NAPI_FUNCTION("close", JSClose)
306 };
307 napi_define_sendable_class(env, PAH_FETCH_FILE_RESULT_SENDABLE_CLASS_NAME.c_str(), NAPI_AUTO_LENGTH,
308 FetchFileResultNapiConstructor, nullptr,
309 sizeof(props) / sizeof(props[0]), props, nullptr, &ctorObj);
310 NAPI_CALL(env, napi_create_reference(env, ctorObj, NAPI_INIT_REF_COUNT, &photoAccessHelperConstructor_));
311 NAPI_CALL(env, napi_set_named_property(env, exports, PAH_FETCH_FILE_RESULT_SENDABLE_CLASS_NAME.c_str(), ctorObj));
312 return exports;
313 }
314
CheckIfFFRNapiNotEmpty(SendableFetchFileResultNapi * obj)315 static bool CheckIfFFRNapiNotEmpty(SendableFetchFileResultNapi* obj)
316 {
317 if (obj == nullptr) {
318 NAPI_INFO_LOG("SendableFetchFileResultNapi is nullptr");
319 return false;
320 }
321 if (obj->CheckIfPropertyPtrNull()) {
322 NAPI_INFO_LOG("PropertyPtr in SendableFetchFileResultNapi is nullptr");
323 return false;
324 }
325 return true;
326 }
327
JSGetCount(napi_env env,napi_callback_info info)328 napi_value SendableFetchFileResultNapi::JSGetCount(napi_env env, napi_callback_info info)
329 {
330 napi_status status;
331 napi_value jsResult = nullptr;
332 SendableFetchFileResultNapi* obj = nullptr;
333 int32_t count = 0;
334 napi_value thisVar = nullptr;
335
336 MediaLibraryTracer tracer;
337 tracer.Start("JSGetCount");
338
339 napi_get_undefined(env, &jsResult);
340 GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
341 if (status != napi_ok || thisVar == nullptr) {
342 NAPI_ERR_LOG("JSGetCount Invalid arguments!, status: %{public}d", status);
343 NAPI_ASSERT(env, false, "JSGetCount thisVar == nullptr");
344 }
345
346 status = napi_unwrap_sendable(env, thisVar, reinterpret_cast<void **>(&obj));
347 if ((status == napi_ok) && CheckIfFFRNapiNotEmpty(obj)) {
348 switch (obj->GetFetchResType()) {
349 case FetchResType::TYPE_FILE:
350 count = obj->GetFetchFileResultObject()->GetCount();
351 break;
352 case FetchResType::TYPE_ALBUM:
353 count = obj->GetFetchAlbumResultObject()->GetCount();
354 break;
355 case FetchResType::TYPE_PHOTOALBUM:
356 count = obj->GetFetchPhotoAlbumResultObject()->GetCount();
357 break;
358 case FetchResType::TYPE_SMARTALBUM:
359 count = obj->GetFetchSmartAlbumResultObject()->GetCount();
360 break;
361 default:
362 NAPI_ERR_LOG("unsupported FetchResType");
363 break;
364 }
365 if (count < 0) {
366 NapiError::ThrowError(env, JS_INNER_FAIL, "Failed to get count");
367 return nullptr;
368 }
369 napi_create_int32(env, count, &jsResult);
370 } else {
371 NapiError::ThrowError(env, JS_ERR_PARAMETER_INVALID, "Failed to get native obj");
372 return nullptr;
373 }
374
375 return jsResult;
376 }
377
GetNapiResFromAsset(napi_env env,FetchFileResultSendableAsyncContext * context,unique_ptr<SendableJSAsyncContextOutput> & jsContext)378 static void GetNapiResFromAsset(napi_env env, FetchFileResultSendableAsyncContext *context,
379 unique_ptr<SendableJSAsyncContextOutput> &jsContext)
380 {
381 napi_value jsAsset;
382 switch (context->objectPtr->fetchResType_) {
383 case FetchResType::TYPE_FILE:
384 context->fileAsset->SetUserId(context->objectPtr->fetchFileResult_->GetUserId());
385 jsAsset = SendableFileAssetNapi::CreateFileAsset(env, context->fileAsset);
386 break;
387 case FetchResType::TYPE_ALBUM:
388 jsAsset = AlbumNapi::CreateAlbumNapi(env, context->albumAsset);
389 break;
390 case FetchResType::TYPE_PHOTOALBUM:
391 context->photoAlbum->SetUserId(context->objectPtr->fetchPhotoAlbumResult_->GetUserId());
392 jsAsset = SendablePhotoAlbumNapi::CreatePhotoAlbumNapi(env, context->photoAlbum);
393 break;
394 case FetchResType::TYPE_SMARTALBUM:
395 jsAsset = SmartAlbumNapi::CreateSmartAlbumNapi(env, context->smartAlbumAsset);
396 break;
397 default:
398 NAPI_ERR_LOG("unsupported FetchResType");
399 break;
400 }
401
402 if (jsAsset == nullptr) {
403 NAPI_ERR_LOG("Failed to get file asset napi object");
404 napi_get_undefined(env, &jsContext->data);
405 SendableMediaLibraryNapiUtils::CreateNapiErrorObject(env, jsContext->error, JS_INNER_FAIL,
406 "System inner fail");
407 } else {
408 jsContext->data = jsAsset;
409 napi_get_undefined(env, &jsContext->error);
410 jsContext->status = true;
411 }
412 }
413
GetPositionObjectCompleteCallback(napi_env env,napi_status status,FetchFileResultSendableAsyncContext * context)414 static void GetPositionObjectCompleteCallback(napi_env env, napi_status status,
415 FetchFileResultSendableAsyncContext* context)
416 {
417 MediaLibraryTracer tracer;
418 tracer.Start("GetPositionObjectCompleteCallback");
419
420 CHECK_NULL_PTR_RETURN_VOID(context, "Async context is null");
421
422 unique_ptr<SendableJSAsyncContextOutput> jsContext = make_unique<SendableJSAsyncContextOutput>();
423 jsContext->status = false;
424
425 GetNapiResFromAsset(env, context, jsContext);
426
427 if (context->work != nullptr) {
428 SendableMediaLibraryNapiUtils::InvokeJSAsyncMethod(env, context->deferred, context->callbackRef,
429 context->work, *jsContext);
430 }
431
432 delete context;
433 }
434
JSGetFirstObject(napi_env env,napi_callback_info info)435 napi_value SendableFetchFileResultNapi::JSGetFirstObject(napi_env env, napi_callback_info info)
436 {
437 napi_status status;
438 napi_value result = nullptr;
439 const int32_t refCount = 1;
440 napi_value resource = nullptr;
441 size_t argc = ARGS_ONE;
442 napi_value argv[ARGS_ONE] = {0};
443 napi_value thisVar = nullptr;
444
445 GET_JS_ARGS(env, info, argc, argv, thisVar);
446 NAPI_ASSERT(env, argc <= ARGS_ONE, "requires 1 parameter");
447 napi_get_undefined(env, &result);
448
449 unique_ptr<FetchFileResultSendableAsyncContext> asyncContext = make_unique<FetchFileResultSendableAsyncContext>();
450 status = napi_unwrap_sendable(env, thisVar, reinterpret_cast<void **>(&asyncContext->objectInfo));
451 if (status == napi_ok && CheckIfFFRNapiNotEmpty(asyncContext->objectInfo)) {
452 if (argc == ARGS_ONE) {
453 GET_JS_ASYNC_CB_REF(env, argv[PARAM0], refCount, asyncContext->callbackRef);
454 }
455
456 NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result);
457 NAPI_CREATE_RESOURCE_NAME(env, resource, "JSGetFirstObject", asyncContext);
458
459 asyncContext->objectPtr = asyncContext->objectInfo->propertyPtr;
460 CHECK_NULL_PTR_RETURN_UNDEFINED(env, asyncContext->objectPtr, result, "propertyPtr is nullptr");
461
462 status = napi_create_async_work(
463 env, nullptr, resource, [](napi_env env, void *data) {
464 auto context = static_cast<FetchFileResultSendableAsyncContext*>(data);
465 context->GetFirstAsset();
466 },
467 reinterpret_cast<napi_async_complete_callback>(GetPositionObjectCompleteCallback),
468 static_cast<void *>(asyncContext.get()), &asyncContext->work);
469 if (status != napi_ok) {
470 napi_get_undefined(env, &result);
471 } else {
472 napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated);
473 asyncContext.release();
474 }
475 } else {
476 NAPI_ERR_LOG("JSGetFirstObject obj == nullptr, status: %{public}d", status);
477 NAPI_ASSERT(env, false, "JSGetFirstObject obj == nullptr");
478 }
479
480 return result;
481 }
482
JSGetNextObject(napi_env env,napi_callback_info info)483 napi_value SendableFetchFileResultNapi::JSGetNextObject(napi_env env, napi_callback_info info)
484 {
485 napi_status status;
486 napi_value result = nullptr;
487 const int32_t refCount = 1;
488 napi_value resource = nullptr;
489 size_t argc = ARGS_ONE;
490 napi_value argv[ARGS_ONE] = {0};
491 napi_value thisVar = nullptr;
492
493 GET_JS_ARGS(env, info, argc, argv, thisVar);
494 NAPI_ASSERT(env, argc <= ARGS_ONE, "requires 1 parameter");
495
496 napi_get_undefined(env, &result);
497 unique_ptr<FetchFileResultSendableAsyncContext> asyncContext = make_unique<FetchFileResultSendableAsyncContext>();
498 status = napi_unwrap_sendable(env, thisVar, reinterpret_cast<void **>(&asyncContext->objectInfo));
499 if (status == napi_ok && CheckIfFFRNapiNotEmpty(asyncContext->objectInfo)) {
500 if (argc == ARGS_ONE) {
501 GET_JS_ASYNC_CB_REF(env, argv[PARAM0], refCount, asyncContext->callbackRef);
502 }
503
504 NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result);
505 NAPI_CREATE_RESOURCE_NAME(env, resource, "JSGetNextObject", asyncContext);
506
507 asyncContext->objectPtr = asyncContext->objectInfo->propertyPtr;
508 CHECK_NULL_PTR_RETURN_UNDEFINED(env, asyncContext->objectPtr, result, "propertyPtr is nullptr");
509
510 status = napi_create_async_work(
511 env, nullptr, resource, [](napi_env env, void *data) {
512 auto context = static_cast<FetchFileResultSendableAsyncContext*>(data);
513 context->GetNextObject();
514 },
515 reinterpret_cast<napi_async_complete_callback>(GetPositionObjectCompleteCallback),
516 static_cast<void *>(asyncContext.get()), &asyncContext->work);
517 if (status != napi_ok) {
518 napi_get_undefined(env, &result);
519 } else {
520 napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated);
521 asyncContext.release();
522 }
523 } else {
524 NAPI_ERR_LOG("JSGetNextObject obj == nullptr, status: %{public}d", status);
525 NAPI_ASSERT(env, false, "JSGetNextObject obj == nullptr");
526 }
527
528 return result;
529 }
530
GetAsset(napi_env env,vector<std::unique_ptr<FileAsset>> & array,int index)531 static napi_value GetAsset(napi_env env, vector<std::unique_ptr<FileAsset>> &array, int index)
532 {
533 return SendableFileAssetNapi::CreateFileAsset(env, array[index]);
534 }
535
GetAsset(napi_env env,vector<std::unique_ptr<AlbumAsset>> & array,int index)536 static napi_value GetAsset(napi_env env, vector<std::unique_ptr<AlbumAsset>> &array, int index)
537 {
538 return AlbumNapi::CreateAlbumNapi(env, array[index]);
539 }
540
GetAsset(napi_env env,vector<std::unique_ptr<PhotoAlbum>> & array,int index)541 static napi_value GetAsset(napi_env env, vector<std::unique_ptr<PhotoAlbum>> &array, int index)
542 {
543 return SendablePhotoAlbumNapi::CreatePhotoAlbumNapi(env, array[index]);
544 }
545
GetAsset(napi_env env,vector<std::unique_ptr<SmartAlbumAsset>> & array,int index)546 static napi_value GetAsset(napi_env env, vector<std::unique_ptr<SmartAlbumAsset>> &array, int index)
547 {
548 return SmartAlbumNapi::CreateSmartAlbumNapi(env, array[index]);
549 }
550
551 template<class T>
GetAssetFromArray(napi_env env,FetchFileResultSendableAsyncContext * context,T & array,unique_ptr<SendableJSAsyncContextOutput> & jsContext)552 static void GetAssetFromArray(napi_env env, FetchFileResultSendableAsyncContext* context, T& array,
553 unique_ptr<SendableJSAsyncContextOutput> &jsContext)
554 {
555 napi_value jsFileArray = nullptr;
556 napi_create_array_with_length(env, array.size(), &jsFileArray);
557 napi_value jsFileAsset = nullptr;
558 size_t i = 0;
559 for (i = 0; i < array.size(); i++) {
560 jsFileAsset = GetAsset(env, array, i);
561 if ((jsFileAsset == nullptr) || (napi_set_element(env, jsFileArray, i, jsFileAsset) != napi_ok)) {
562 NAPI_ERR_LOG("Failed to get file asset napi object");
563 napi_get_undefined(env, &jsContext->data);
564 SendableMediaLibraryNapiUtils::CreateNapiErrorObject(env, jsContext->error, ERR_MEM_ALLOCATION,
565 "Failed to create js object");
566 break;
567 }
568 }
569 if (i == array.size()) {
570 jsContext->data = jsFileArray;
571 napi_get_undefined(env, &jsContext->error);
572 jsContext->status = true;
573 }
574 }
575
GetAllObjectCompleteCallback(napi_env env,napi_status status,FetchFileResultSendableAsyncContext * context)576 static void GetAllObjectCompleteCallback(napi_env env, napi_status status, FetchFileResultSendableAsyncContext* context)
577 {
578 MediaLibraryTracer tracer;
579 tracer.Start("GetAllObjectCompleteCallback");
580 CHECK_NULL_PTR_RETURN_VOID(context, "Async context is null");
581 unique_ptr<SendableJSAsyncContextOutput> jsContext = make_unique<SendableJSAsyncContextOutput>();
582 jsContext->status = false;
583
584 switch (context->objectPtr->fetchResType_) {
585 case FetchResType::TYPE_FILE:
586 GetAssetFromArray(env, context, context->fileAssetArray, jsContext);
587 break;
588 case FetchResType::TYPE_ALBUM:
589 GetAssetFromArray(env, context, context->fileAlbumArray, jsContext);
590 break;
591 case FetchResType::TYPE_PHOTOALBUM:
592 GetAssetFromArray(env, context, context->filePhotoAlbumArray, jsContext);
593 break;
594 case FetchResType::TYPE_SMARTALBUM:
595 GetAssetFromArray(env, context, context->fileSmartAlbumArray, jsContext);
596 break;
597 default:
598 NAPI_ERR_LOG("unsupported FetchResType");
599 napi_get_undefined(env, &jsContext->data);
600 SendableMediaLibraryNapiUtils::CreateNapiErrorObject(env, jsContext->error, ERR_INVALID_OUTPUT,
601 "Failed to obtain fileAsset array from DB");
602 }
603
604 if (context->work != nullptr) {
605 int64_t start = MediaFileUtils::UTCTimeMilliSeconds();
606 SendableMediaLibraryNapiUtils::InvokeJSAsyncMethod(env, context->deferred, context->callbackRef,
607 context->work, *jsContext);
608 int64_t end = MediaFileUtils::UTCTimeMilliSeconds();
609 int64_t normalTime = 500;
610 if ((long)(end - start) >= normalTime) {
611 NAPI_INFO_LOG("InvokeJSAsync dir cost: %{public}ld", (long)(end - start));
612 }
613 }
614
615 delete context;
616 }
617
GetFetchFileResultObject()618 std::shared_ptr<FetchResult<FileAsset>> SendableFetchFileResultNapi::GetFetchFileResultObject()
619 {
620 return propertyPtr->fetchFileResult_;
621 }
622
GetFetchAlbumResultObject()623 std::shared_ptr<FetchResult<AlbumAsset>> SendableFetchFileResultNapi::GetFetchAlbumResultObject()
624 {
625 return propertyPtr->fetchAlbumResult_;
626 }
627
GetFetchPhotoAlbumResultObject()628 std::shared_ptr<FetchResult<PhotoAlbum>> SendableFetchFileResultNapi::GetFetchPhotoAlbumResultObject()
629 {
630 return propertyPtr->fetchPhotoAlbumResult_;
631 }
632
GetFetchSmartAlbumResultObject()633 std::shared_ptr<FetchResult<SmartAlbumAsset>> SendableFetchFileResultNapi::GetFetchSmartAlbumResultObject()
634 {
635 return propertyPtr->fetchSmartAlbumResult_;
636 }
637
GetAllObjectFromFetchResult(const FetchFileResultSendableAsyncContext & asyncContext)638 void GetAllObjectFromFetchResult(const FetchFileResultSendableAsyncContext &asyncContext)
639 {
640 MediaLibraryTracer tracer;
641 tracer.Start("GetAllObjectFromFetchResult");
642
643 FetchFileResultSendableAsyncContext *context = const_cast<FetchFileResultSendableAsyncContext *>(&asyncContext);
644 context->GetAllObjectFromFetchResult();
645 }
646
JSGetAllObject(napi_env env,napi_callback_info info)647 napi_value SendableFetchFileResultNapi::JSGetAllObject(napi_env env, napi_callback_info info)
648 {
649 napi_status status;
650 napi_value result = nullptr;
651 const int32_t refCount = 1;
652 napi_value resource = nullptr;
653 size_t argc = ARGS_ONE;
654 napi_value argv[ARGS_ONE] = {0};
655 napi_value thisVar = nullptr;
656
657 MediaLibraryTracer tracer;
658 tracer.Start("JSGetAllObject");
659
660 GET_JS_ARGS(env, info, argc, argv, thisVar);
661 NAPI_ASSERT(env, argc <= ARGS_ONE, "requires 1 parameter maximum");
662
663 napi_get_undefined(env, &result);
664 unique_ptr<FetchFileResultSendableAsyncContext> asyncContext = make_unique<FetchFileResultSendableAsyncContext>();
665 status = napi_unwrap_sendable(env, thisVar, reinterpret_cast<void **>(&asyncContext->objectInfo));
666 if (status == napi_ok && CheckIfFFRNapiNotEmpty(asyncContext->objectInfo)) {
667 if (argc == ARGS_ONE) {
668 GET_JS_ASYNC_CB_REF(env, argv[PARAM0], refCount, asyncContext->callbackRef);
669 }
670
671 NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result);
672 NAPI_CREATE_RESOURCE_NAME(env, resource, "JSGetAllObject", asyncContext);
673
674 asyncContext->objectPtr = asyncContext->objectInfo->propertyPtr;
675 CHECK_NULL_PTR_RETURN_UNDEFINED(env, asyncContext->objectPtr, result, "propertyPtr is nullptr");
676
677 status = napi_create_async_work(
678 env, nullptr, resource, [](napi_env env, void *data) {
679 auto context = static_cast<FetchFileResultSendableAsyncContext*>(data);
680 GetAllObjectFromFetchResult(*context);
681 },
682 reinterpret_cast<napi_async_complete_callback>(GetAllObjectCompleteCallback),
683 static_cast<void *>(asyncContext.get()), &asyncContext->work);
684 if (status != napi_ok) {
685 napi_get_undefined(env, &result);
686 } else {
687 napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated);
688 asyncContext.release();
689 }
690 } else {
691 NAPI_ERR_LOG("JSGetAllObject obj == nullptr, status: %{public}d", status);
692 NAPI_ASSERT(env, false, "JSGetAllObject obj == nullptr");
693 }
694
695 return result;
696 }
697
JSClose(napi_env env,napi_callback_info info)698 napi_value SendableFetchFileResultNapi::JSClose(napi_env env, napi_callback_info info)
699 {
700 napi_status status;
701 napi_value jsResult = nullptr;
702 SendableFetchFileResultNapi* obj = nullptr;
703 napi_value thisVar = nullptr;
704
705 MediaLibraryTracer tracer;
706 tracer.Start("JSClose");
707
708 napi_get_undefined(env, &jsResult);
709 GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
710 if (status != napi_ok || thisVar == nullptr) {
711 NAPI_ERR_LOG("Invalid arguments!, status: %{public}d", status);
712 return jsResult;
713 }
714 status = napi_unwrap_sendable(env, thisVar, reinterpret_cast<void **>(&obj));
715 if ((status == napi_ok) && (obj != nullptr)) {
716 obj->propertyPtr = nullptr;
717 }
718 status = napi_remove_wrap_sendable(env, thisVar, reinterpret_cast<void **>(&obj));
719 if ((status == napi_ok) && (obj != nullptr)) {
720 napi_create_int32(env, E_SUCCESS, &jsResult);
721 } else {
722 NAPI_INFO_LOG("JSClose obj == nullptr");
723 }
724
725 NAPI_DEBUG_LOG("JSClose OUT!");
726 return jsResult;
727 }
728
GetFirstAsset()729 void FetchFileResultSendableAsyncContext::GetFirstAsset()
730 {
731 switch (objectPtr->fetchResType_) {
732 case FetchResType::TYPE_FILE: {
733 fileAsset = objectPtr->fetchFileResult_->GetFirstObject();
734 break;
735 }
736 case FetchResType::TYPE_ALBUM: {
737 albumAsset = objectPtr->fetchAlbumResult_->GetFirstObject();
738 break;
739 }
740 case FetchResType::TYPE_PHOTOALBUM: {
741 photoAlbum = objectPtr->fetchPhotoAlbumResult_->GetFirstObject();
742 break;
743 }
744 case FetchResType::TYPE_SMARTALBUM: {
745 smartAlbumAsset = objectPtr->fetchSmartAlbumResult_->GetFirstObject();
746 break;
747 }
748 default:
749 NAPI_ERR_LOG("unsupported FetchResType");
750 break;
751 }
752 }
753
GetObjectAtPosition()754 void FetchFileResultSendableAsyncContext::GetObjectAtPosition()
755 {
756 switch (objectPtr->fetchResType_) {
757 case FetchResType::TYPE_FILE: {
758 fileAsset = objectPtr->fetchFileResult_->GetObjectAtPosition(position);
759 break;
760 }
761 case FetchResType::TYPE_ALBUM: {
762 albumAsset = objectPtr->fetchAlbumResult_->GetObjectAtPosition(position);
763 break;
764 }
765 case FetchResType::TYPE_PHOTOALBUM: {
766 photoAlbum = objectPtr->fetchPhotoAlbumResult_->GetObjectAtPosition(position);
767 break;
768 }
769 case FetchResType::TYPE_SMARTALBUM: {
770 smartAlbumAsset = objectPtr->fetchSmartAlbumResult_->GetObjectAtPosition(position);
771 break;
772 }
773 default:
774 NAPI_ERR_LOG("unsupported FetchResType");
775 break;
776 }
777 }
778
GetLastObject()779 void FetchFileResultSendableAsyncContext::GetLastObject()
780 {
781 switch (objectPtr->fetchResType_) {
782 case FetchResType::TYPE_FILE: {
783 fileAsset = objectPtr->fetchFileResult_->GetLastObject();
784 break;
785 }
786 case FetchResType::TYPE_ALBUM: {
787 albumAsset = objectPtr->fetchAlbumResult_->GetLastObject();
788 break;
789 }
790 case FetchResType::TYPE_PHOTOALBUM: {
791 photoAlbum = objectPtr->fetchPhotoAlbumResult_->GetLastObject();
792 break;
793 }
794 case FetchResType::TYPE_SMARTALBUM: {
795 smartAlbumAsset = objectPtr->fetchSmartAlbumResult_->GetLastObject();
796 break;
797 }
798 default:
799 NAPI_ERR_LOG("unsupported FetchResType");
800 break;
801 }
802 }
803
GetNextObject()804 void FetchFileResultSendableAsyncContext::GetNextObject()
805 {
806 switch (objectPtr->fetchResType_) {
807 case FetchResType::TYPE_FILE: {
808 fileAsset = objectPtr->fetchFileResult_->GetNextObject();
809 break;
810 }
811 case FetchResType::TYPE_ALBUM: {
812 albumAsset = objectPtr->fetchAlbumResult_->GetNextObject();
813 break;
814 }
815 case FetchResType::TYPE_PHOTOALBUM: {
816 photoAlbum = objectPtr->fetchPhotoAlbumResult_->GetNextObject();
817 break;
818 }
819 case FetchResType::TYPE_SMARTALBUM: {
820 smartAlbumAsset = objectPtr->fetchSmartAlbumResult_->GetNextObject();
821 break;
822 }
823 default:
824 NAPI_ERR_LOG("unsupported FetchResType");
825 break;
826 }
827 }
828
GetAllObjectFromFetchResult()829 void FetchFileResultSendableAsyncContext::GetAllObjectFromFetchResult()
830 {
831 switch (objectPtr->fetchResType_) {
832 case FetchResType::TYPE_FILE: {
833 auto fetchResult = objectPtr->fetchFileResult_;
834 auto file = fetchResult->GetFirstObject();
835 while (file != nullptr) {
836 file->SetUserId(fetchResult->GetUserId());
837 fileAssetArray.push_back(move(file));
838 file = fetchResult->GetNextObject();
839 }
840 break;
841 }
842 case FetchResType::TYPE_ALBUM: {
843 auto fetchResult = objectPtr->fetchAlbumResult_;
844 auto album = fetchResult->GetFirstObject();
845 while (album != nullptr) {
846 fileAlbumArray.push_back(move(album));
847 album = fetchResult->GetNextObject();
848 }
849 break;
850 }
851 case FetchResType::TYPE_PHOTOALBUM: {
852 auto fetchResult = objectPtr->fetchPhotoAlbumResult_;
853 auto photoAlbum = fetchResult->GetFirstObject();
854 while (photoAlbum != nullptr) {
855 photoAlbum->SetUserId(fetchResult->GetUserId());
856 filePhotoAlbumArray.push_back(move(photoAlbum));
857 photoAlbum = fetchResult->GetNextObject();
858 }
859 break;
860 }
861 case FetchResType::TYPE_SMARTALBUM: {
862 auto fetchResult = objectPtr->fetchSmartAlbumResult_;
863 auto smartAlbum = fetchResult->GetFirstObject();
864 while (smartAlbum != nullptr) {
865 fileSmartAlbumArray.push_back(move(smartAlbum));
866 smartAlbum = fetchResult->GetNextObject();
867 }
868 break;
869 }
870 default:
871 NAPI_ERR_LOG("unsupported FetchResType");
872 break;
873 }
874 }
875
CheckIfPropertyPtrNull()876 bool SendableFetchFileResultNapi::CheckIfPropertyPtrNull()
877 {
878 return propertyPtr == nullptr;
879 }
880
JSIsAfterLast(napi_env env,napi_callback_info info)881 napi_value SendableFetchFileResultNapi::JSIsAfterLast(napi_env env, napi_callback_info info)
882 {
883 napi_status status;
884 napi_value jsResult = nullptr;
885 SendableFetchFileResultNapi* obj = nullptr;
886 bool isAfterLast = false;
887 napi_value thisVar = nullptr;
888
889 MediaLibraryTracer tracer;
890 tracer.Start("JSIsAfterLast");
891
892 napi_get_undefined(env, &jsResult);
893 GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
894 if (status != napi_ok || thisVar == nullptr) {
895 NAPI_ERR_LOG("JSIsAfterLast Invalid arguments!, status: %{public}d", status);
896 NAPI_ASSERT(env, false, "JSIsAfterLast thisVar == nullptr");
897 }
898
899 status = napi_unwrap_sendable(env, thisVar, reinterpret_cast<void **>(&obj));
900 if ((status == napi_ok) && CheckIfFFRNapiNotEmpty(obj)) {
901 switch (obj->GetFetchResType()) {
902 case FetchResType::TYPE_FILE:
903 isAfterLast = obj->GetFetchFileResultObject()->IsAtLastRow();
904 break;
905 case FetchResType::TYPE_ALBUM:
906 isAfterLast = obj->GetFetchAlbumResultObject()->IsAtLastRow();
907 break;
908 case FetchResType::TYPE_PHOTOALBUM:
909 isAfterLast = obj->GetFetchPhotoAlbumResultObject()->IsAtLastRow();
910 break;
911 case FetchResType::TYPE_SMARTALBUM:
912 isAfterLast = obj->GetFetchSmartAlbumResultObject()->IsAtLastRow();
913 break;
914 default:
915 NAPI_ERR_LOG("unsupported FetchResType");
916 break;
917 }
918 napi_get_boolean(env, isAfterLast, &jsResult);
919 } else {
920 NAPI_ERR_LOG("JSIsAfterLast obj == nullptr, status: %{public}d", status);
921 NAPI_ASSERT(env, false, "JSIsAfterLast obj == nullptr");
922 }
923
924 return jsResult;
925 }
926
JSGetLastObject(napi_env env,napi_callback_info info)927 napi_value SendableFetchFileResultNapi::JSGetLastObject(napi_env env, napi_callback_info info)
928 {
929 napi_status status;
930 napi_value result = nullptr;
931 const int32_t refCount = 1;
932 napi_value resource = nullptr;
933 size_t argc = ARGS_ONE;
934 napi_value argv[ARGS_ONE] = {0};
935 napi_value thisVar = nullptr;
936
937 GET_JS_ARGS(env, info, argc, argv, thisVar);
938 NAPI_ASSERT(env, argc <= ARGS_ONE, "requires 1 parameter");
939
940 napi_get_undefined(env, &result);
941 unique_ptr<FetchFileResultSendableAsyncContext> asyncContext = make_unique<FetchFileResultSendableAsyncContext>();
942 status = napi_unwrap_sendable(env, thisVar, reinterpret_cast<void **>(&asyncContext->objectInfo));
943 if (status == napi_ok && CheckIfFFRNapiNotEmpty(asyncContext->objectInfo)) {
944 if (argc == ARGS_ONE) {
945 GET_JS_ASYNC_CB_REF(env, argv[PARAM0], refCount, asyncContext->callbackRef);
946 }
947
948 NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result);
949 NAPI_CREATE_RESOURCE_NAME(env, resource, "JSGetLastObject", asyncContext);
950
951 asyncContext->objectPtr = asyncContext->objectInfo->propertyPtr;
952 CHECK_NULL_PTR_RETURN_UNDEFINED(env, asyncContext->objectPtr, result, "propertyPtr is nullptr");
953
954 status = napi_create_async_work(
955 env, nullptr, resource, [](napi_env env, void *data) {
956 auto context = static_cast<FetchFileResultSendableAsyncContext*>(data);
957 context->GetLastObject();
958 },
959 reinterpret_cast<napi_async_complete_callback>(GetPositionObjectCompleteCallback),
960 static_cast<void *>(asyncContext.get()), &asyncContext->work);
961 if (status != napi_ok) {
962 napi_get_undefined(env, &result);
963 } else {
964 napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated);
965 asyncContext.release();
966 }
967 } else {
968 NAPI_ERR_LOG("JSGetLastObject obj == nullptr, status: %{public}d", status);
969 NAPI_ASSERT(env, false, "JSGetLastObject obj == nullptr");
970 }
971
972 return result;
973 }
974
JSGetPositionObject(napi_env env,napi_callback_info info)975 napi_value SendableFetchFileResultNapi::JSGetPositionObject(napi_env env, napi_callback_info info)
976 {
977 napi_status status;
978 napi_value result = nullptr;
979 const int32_t refCount = 1;
980 napi_valuetype type = napi_undefined;
981 napi_value resource = nullptr;
982 size_t argc = ARGS_TWO;
983 napi_value argv[ARGS_TWO] = {0};
984 napi_value thisVar = nullptr;
985
986 MediaLibraryTracer tracer;
987 tracer.Start("JSGetPositionObject");
988
989 GET_JS_ARGS(env, info, argc, argv, thisVar);
990 NAPI_ASSERT(env, (argc == ARGS_ONE || argc == ARGS_TWO), "requires 2 parameter maximum");
991
992 napi_get_undefined(env, &result);
993 unique_ptr<FetchFileResultSendableAsyncContext> asyncContext = make_unique<FetchFileResultSendableAsyncContext>();
994 status = napi_unwrap_sendable(env, thisVar, reinterpret_cast<void **>(&asyncContext->objectInfo));
995 if (status == napi_ok && CheckIfFFRNapiNotEmpty(asyncContext->objectInfo)) {
996 // Check the arguments and their types
997 napi_typeof(env, argv[PARAM0], &type);
998 if (type == napi_number) {
999 napi_get_value_int32(env, argv[PARAM0], &(asyncContext->position));
1000 } else {
1001 NAPI_ERR_LOG("Argument mismatch, type: %{public}d", type);
1002 return result;
1003 }
1004
1005 if (argc == ARGS_TWO) {
1006 GET_JS_ASYNC_CB_REF(env, argv[PARAM1], refCount, asyncContext->callbackRef);
1007 }
1008
1009 NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result);
1010 NAPI_CREATE_RESOURCE_NAME(env, resource, "JSGetPositionObject", asyncContext);
1011
1012 asyncContext->objectPtr = asyncContext->objectInfo->propertyPtr;
1013 CHECK_NULL_PTR_RETURN_UNDEFINED(env, asyncContext->objectPtr, result, "propertyPtr is nullptr");
1014
1015 status = napi_create_async_work(
1016 env, nullptr, resource, [](napi_env env, void *data) {
1017 auto context = static_cast<FetchFileResultSendableAsyncContext*>(data);
1018 context->GetObjectAtPosition();
1019 },
1020 reinterpret_cast<napi_async_complete_callback>(GetPositionObjectCompleteCallback),
1021 static_cast<void *>(asyncContext.get()), &asyncContext->work);
1022 if (status != napi_ok) {
1023 napi_get_undefined(env, &result);
1024 } else {
1025 napi_queue_async_work_with_qos(env, asyncContext->work, napi_qos_user_initiated);
1026 asyncContext.release();
1027 }
1028 } else {
1029 NAPI_ERR_LOG("JSGetPositionObject obj == nullptr, status: %{public}d", status);
1030 NAPI_ASSERT(env, false, "JSGetPositionObject obj == nullptr");
1031 }
1032
1033 return result;
1034 }
1035 } // namespace Media
1036 } // namespace OHOS