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