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