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 "AlbumNapi"
16 
17 #include "album_napi.h"
18 
19 #include "media_file_asset_columns.h"
20 #include "media_file_utils.h"
21 #include "media_library_napi.h"
22 #include "medialibrary_client_errno.h"
23 #include "medialibrary_napi_log.h"
24 #include "medialibrary_tracer.h"
25 #include "userfile_client.h"
26 #include "userfile_manager_types.h"
27 
28 using OHOS::HiviewDFX::HiLog;
29 using OHOS::HiviewDFX::HiLogLabel;
30 
31 namespace OHOS {
32 namespace Media {
33 using namespace std;
34 using namespace OHOS::DataShare;
35 thread_local napi_ref AlbumNapi::sConstructor_ = nullptr;
36 thread_local AlbumAsset *AlbumNapi::sAlbumData_ = nullptr;
37 using CompleteCallback = napi_async_complete_callback;
38 
39 thread_local napi_ref AlbumNapi::userFileMgrConstructor_ = nullptr;
40 thread_local napi_ref AlbumNapi::photoAccessHelperConstructor_ = nullptr;
41 
AlbumNapi()42 AlbumNapi::AlbumNapi()
43     : env_(nullptr) {}
44 
45 AlbumNapi::~AlbumNapi() = default;
46 
AlbumNapiDestructor(napi_env env,void * nativeObject,void * finalize_hint)47 void AlbumNapi::AlbumNapiDestructor(napi_env env, void *nativeObject, void *finalize_hint)
48 {
49     AlbumNapi *album = reinterpret_cast<AlbumNapi*>(nativeObject);
50     if (album != nullptr) {
51         delete album;
52         album = nullptr;
53     }
54 }
55 
Init(napi_env env,napi_value exports)56 napi_value AlbumNapi::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 album_props[] = {
63         DECLARE_NAPI_GETTER("albumId", JSGetAlbumId),
64         DECLARE_NAPI_GETTER_SETTER("albumName", JSGetAlbumName, JSAlbumNameSetter),
65         DECLARE_NAPI_GETTER("albumUri", JSGetAlbumUri),
66         DECLARE_NAPI_GETTER("dateModified", JSGetAlbumDateModified),
67         DECLARE_NAPI_GETTER("count", JSGetCount),
68         DECLARE_NAPI_GETTER("relativePath", JSGetAlbumRelativePath),
69         DECLARE_NAPI_GETTER("coverUri", JSGetCoverUri),
70         DECLARE_NAPI_FUNCTION("commitModify", JSCommitModify),
71         DECLARE_NAPI_GETTER_SETTER("path", JSGetAlbumPath, JSSetAlbumPath),
72         DECLARE_NAPI_GETTER("virtual", JSGetAlbumVirtual),
73         DECLARE_NAPI_FUNCTION("getFileAssets", JSGetAlbumFileAssets)
74     };
75 
76     status = napi_define_class(env, ALBUM_NAPI_CLASS_NAME.c_str(), NAPI_AUTO_LENGTH,
77                                AlbumNapiConstructor, nullptr,
78                                sizeof(album_props) / sizeof(album_props[PARAM0]),
79                                album_props, &ctorObj);
80     if (status == napi_ok) {
81         status = napi_create_reference(env, ctorObj, refCount, &sConstructor_);
82         if (status == napi_ok) {
83             status = napi_set_named_property(env, exports, ALBUM_NAPI_CLASS_NAME.c_str(), ctorObj);
84             if (status == napi_ok) {
85                 return exports;
86             }
87         }
88     }
89 
90     return nullptr;
91 }
92 
UserFileMgrInit(napi_env env,napi_value exports)93 napi_value AlbumNapi::UserFileMgrInit(napi_env env, napi_value exports)
94 {
95     NapiClassInfo info = {
96         .name = USERFILEMGR_ALBUM_NAPI_CLASS_NAME,
97         .ref = &userFileMgrConstructor_,
98         .constructor = AlbumNapiConstructor,
99         .props = {
100             DECLARE_NAPI_FUNCTION("getPhotoAssets", UserFileMgrGetAssets),
101             DECLARE_NAPI_FUNCTION("commitModify", UserFileMgrCommitModify),
102             DECLARE_NAPI_GETTER_SETTER("albumName", JSGetAlbumName, JSAlbumNameSetter),
103             DECLARE_NAPI_GETTER("albumUri", JSGetAlbumUri),
104             DECLARE_NAPI_GETTER("dateModified", JSGetAlbumDateModified),
105             DECLARE_NAPI_GETTER("count", JSGetCount),
106             DECLARE_NAPI_GETTER("relativePath", JSGetAlbumRelativePath),
107             DECLARE_NAPI_GETTER("coverUri", JSGetCoverUri)
108         }
109     };
110 
111     MediaLibraryNapiUtils::NapiDefineClass(env, exports, info);
112     return exports;
113 }
114 
PhotoAccessHelperInit(napi_env env,napi_value exports)115 napi_value AlbumNapi::PhotoAccessHelperInit(napi_env env, napi_value exports)
116 {
117     NapiClassInfo info = {
118         .name = PHOTOACCESSHELPER_ALBUM_NAPI_CLASS_NAME,
119         .ref = &photoAccessHelperConstructor_,
120         .constructor = AlbumNapiConstructor,
121         .props = {
122             DECLARE_NAPI_FUNCTION("getAssets", PhotoAccessHelperGetAssets),
123             DECLARE_NAPI_FUNCTION("commitModify", PhotoAccessHelperCommitModify),
124             DECLARE_NAPI_GETTER_SETTER("albumName", JSGetAlbumName, JSAlbumNameSetter),
125             DECLARE_NAPI_GETTER("albumUri", JSGetAlbumUri),
126             DECLARE_NAPI_GETTER("count", JSGetCount),
127             DECLARE_NAPI_GETTER("coverUri", JSGetCoverUri)
128         }
129     };
130 
131     MediaLibraryNapiUtils::NapiDefineClass(env, exports, info);
132     return exports;
133 }
134 
SetAlbumNapiProperties()135 void AlbumNapi::SetAlbumNapiProperties()
136 {
137     albumAssetPtr = std::shared_ptr<AlbumAsset>(sAlbumData_);
138 }
139 
140 // Constructor callback
AlbumNapiConstructor(napi_env env,napi_callback_info info)141 napi_value AlbumNapi::AlbumNapiConstructor(napi_env env, napi_callback_info info)
142 {
143     napi_status status;
144     napi_value result = nullptr;
145     napi_value thisVar = nullptr;
146 
147     napi_get_undefined(env, &result);
148     GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
149     if (status == napi_ok && thisVar != nullptr) {
150         std::unique_ptr<AlbumNapi> obj = std::make_unique<AlbumNapi>();
151         if (obj != nullptr) {
152             obj->env_ = env;
153             if (sAlbumData_ != nullptr) {
154                 obj->SetAlbumNapiProperties();
155             }
156 
157             status = napi_wrap(env, thisVar, reinterpret_cast<void *>(obj.get()),
158                                AlbumNapi::AlbumNapiDestructor, nullptr, nullptr);
159             if (status == napi_ok) {
160                 obj.release();
161                 return thisVar;
162             } else {
163                 NAPI_ERR_LOG("Failure wrapping js to native napi. status: %{public}d", status);
164             }
165         }
166     }
167 
168     return result;
169 }
170 
CreateAlbumNapi(napi_env env,unique_ptr<AlbumAsset> & albumData)171 napi_value AlbumNapi::CreateAlbumNapi(napi_env env, unique_ptr<AlbumAsset> &albumData)
172 {
173     if (albumData == nullptr) {
174         return nullptr;
175     }
176 
177     napi_value constructor;
178     napi_ref constructorRef;
179     if (albumData->GetResultNapiType() == ResultNapiType::TYPE_USERFILE_MGR) {
180         constructorRef = userFileMgrConstructor_;
181     } else if (albumData->GetResultNapiType() == ResultNapiType::TYPE_PHOTOACCESS_HELPER) {
182         constructorRef = photoAccessHelperConstructor_;
183     } else {
184         constructorRef = sConstructor_;
185     }
186     NAPI_CALL(env, napi_get_reference_value(env, constructorRef, &constructor));
187 
188     napi_value result = nullptr;
189     sAlbumData_ = albumData.release();
190     NAPI_CALL(env, napi_new_instance(env, constructor, 0, nullptr, &result));
191     sAlbumData_ = nullptr;
192     return result;
193 }
194 
GetAlbumName() const195 std::string AlbumNapi::GetAlbumName() const
196 {
197     return albumAssetPtr->GetAlbumName();
198 }
199 
GetAlbumPath() const200 std::string AlbumNapi::GetAlbumPath() const
201 {
202     return albumAssetPtr->GetAlbumPath();
203 }
204 
GetAlbumId() const205 int32_t AlbumNapi::GetAlbumId() const
206 {
207     return albumAssetPtr->GetAlbumId();
208 }
209 
GetAlbumUri() const210 std::string AlbumNapi::GetAlbumUri() const
211 {
212     return albumAssetPtr->GetAlbumUri();
213 }
214 
GetNetworkId() const215 std::string AlbumNapi::GetNetworkId() const
216 {
217     return MediaFileUtils::GetNetworkIdFromUri(GetAlbumUri());
218 }
219 
220 #ifdef MEDIALIBRARY_COMPATIBILITY
GetAlbumType() const221 PhotoAlbumType AlbumNapi::GetAlbumType() const
222 {
223     return albumAssetPtr->GetAlbumType();
224 }
GetAlbumSubType() const225 PhotoAlbumSubType AlbumNapi::GetAlbumSubType() const
226 {
227     return albumAssetPtr->GetAlbumSubType();
228 }
229 #endif
230 
JSGetAlbumId(napi_env env,napi_callback_info info)231 napi_value AlbumNapi::JSGetAlbumId(napi_env env, napi_callback_info info)
232 {
233     napi_status status;
234     napi_value jsResult = nullptr;
235     napi_value undefinedResult = nullptr;
236     AlbumNapi* obj = nullptr;
237     int32_t id;
238     napi_value thisVar = nullptr;
239 
240     napi_get_undefined(env, &undefinedResult);
241     GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
242     if (status != napi_ok || thisVar == nullptr) {
243         NAPI_ERR_LOG("Invalid arguments! status: %{public}d", status);
244         return undefinedResult;
245     }
246 
247     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
248     if (status == napi_ok && obj != nullptr) {
249         id = obj->GetAlbumId();
250         status = napi_create_int32(env, id, &jsResult);
251         if (status == napi_ok) {
252             return jsResult;
253         }
254     }
255 
256     return undefinedResult;
257 }
258 
JSGetAlbumName(napi_env env,napi_callback_info info)259 napi_value AlbumNapi::JSGetAlbumName(napi_env env, napi_callback_info info)
260 {
261     napi_status status;
262     napi_value jsResult = nullptr;
263     napi_value undefinedResult = nullptr;
264     AlbumNapi* obj = nullptr;
265     std::string name = "";
266     napi_value thisVar = nullptr;
267     napi_get_undefined(env, &undefinedResult);
268     GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
269     if (status != napi_ok || thisVar == nullptr) {
270         NAPI_ERR_LOG("Invalid arguments! status: %{public}d", status);
271         return undefinedResult;
272     }
273 
274     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
275     if (status == napi_ok && obj != nullptr) {
276         name = obj->GetAlbumName();
277         status = napi_create_string_utf8(env, name.c_str(), NAPI_AUTO_LENGTH, &jsResult);
278         if (status == napi_ok) {
279             return jsResult;
280         }
281     }
282 
283     return undefinedResult;
284 }
285 
JSAlbumNameSetter(napi_env env,napi_callback_info info)286 napi_value AlbumNapi::JSAlbumNameSetter(napi_env env, napi_callback_info info)
287 {
288     napi_status status;
289     napi_value jsResult = nullptr;
290     size_t argc = ARGS_ONE;
291     napi_value argv[ARGS_ONE] = {0};
292     size_t res = 0;
293     char buffer[FILENAME_MAX];
294     AlbumNapi* obj = nullptr;
295     napi_value thisVar = nullptr;
296     napi_valuetype valueType = napi_undefined;
297 
298     napi_get_undefined(env, &jsResult);
299     GET_JS_ARGS(env, info, argc, argv, thisVar);
300     NAPI_ASSERT(env, argc == ARGS_ONE, "requires 1 parameter");
301     if (thisVar == nullptr || napi_typeof(env, argv[PARAM0], &valueType) != napi_ok
302         || valueType != napi_string) {
303         NAPI_ERR_LOG("Invalid arguments type! valueType: %{public}d", valueType);
304         return jsResult;
305     }
306 
307     napi_get_value_string_utf8(env, argv[PARAM0], buffer, FILENAME_MAX, &res);
308 
309     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
310     if (status == napi_ok && obj != nullptr) {
311         obj->albumAssetPtr->SetAlbumName(std::string(buffer));
312     } else {
313         NAPI_ERR_LOG("status = %{public}d", status);
314     }
315     return jsResult;
316 }
JSGetAlbumUri(napi_env env,napi_callback_info info)317 napi_value AlbumNapi::JSGetAlbumUri(napi_env env, napi_callback_info info)
318 {
319     napi_status status;
320     napi_value jsResult = nullptr;
321     napi_value undefinedResult = nullptr;
322     AlbumNapi* obj = nullptr;
323     std::string uri = "";
324     napi_value thisVar = nullptr;
325 
326     napi_get_undefined(env, &undefinedResult);
327     GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
328     if (status != napi_ok || thisVar == nullptr) {
329         NAPI_ERR_LOG("Invalid arguments! status: %{public}d", status);
330         return undefinedResult;
331     }
332 
333     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
334     if (status == napi_ok && obj != nullptr) {
335         uri = obj->GetAlbumUri();
336         status = napi_create_string_utf8(env, uri.c_str(), NAPI_AUTO_LENGTH, &jsResult);
337         if (status == napi_ok) {
338             return jsResult;
339         }
340     }
341 
342     return undefinedResult;
343 }
JSGetAlbumDateModified(napi_env env,napi_callback_info info)344 napi_value AlbumNapi::JSGetAlbumDateModified(napi_env env, napi_callback_info info)
345 {
346     napi_status status;
347     napi_value jsResult = nullptr;
348     napi_value undefinedResult = nullptr;
349     AlbumNapi* obj = nullptr;
350     int64_t dateModified;
351     napi_value thisVar = nullptr;
352 
353     napi_get_undefined(env, &undefinedResult);
354     GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
355     if (status != napi_ok || thisVar == nullptr) {
356         NAPI_ERR_LOG("Invalid arguments! status: %{public}d", status);
357         return undefinedResult;
358     }
359 
360     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
361     if (status == napi_ok && obj != nullptr) {
362         dateModified = obj->albumAssetPtr->GetAlbumDateModified() / MSEC_TO_SEC;
363         status = napi_create_int64(env, dateModified, &jsResult);
364         if (status == napi_ok) {
365             return jsResult;
366         }
367     }
368 
369     return undefinedResult;
370 }
JSGetCount(napi_env env,napi_callback_info info)371 napi_value AlbumNapi::JSGetCount(napi_env env, napi_callback_info info)
372 {
373     napi_status status;
374     napi_value jsResult = nullptr;
375     napi_value undefinedResult = nullptr;
376     AlbumNapi *obj = nullptr;
377     int32_t count;
378     napi_value thisVar = nullptr;
379 
380     napi_get_undefined(env, &undefinedResult);
381     GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
382     if (status != napi_ok || thisVar == nullptr) {
383         NAPI_ERR_LOG("Invalid arguments! status: %{public}d", status);
384         return undefinedResult;
385     }
386     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
387     if (status == napi_ok && obj != nullptr) {
388         count = obj->albumAssetPtr->GetCount();
389         status = napi_create_int32(env, count, &jsResult);
390         if (status == napi_ok) {
391             return jsResult;
392         }
393     }
394     return undefinedResult;
395 }
JSGetAlbumRelativePath(napi_env env,napi_callback_info info)396 napi_value AlbumNapi::JSGetAlbumRelativePath(napi_env env, napi_callback_info info)
397 {
398     napi_status status;
399     napi_value jsResult = nullptr;
400     napi_value undefinedResult = nullptr;
401     AlbumNapi* obj = nullptr;
402     std::string relativePath = "";
403     napi_value thisVar = nullptr;
404 
405     napi_get_undefined(env, &undefinedResult);
406     GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
407     if (status != napi_ok || thisVar == nullptr) {
408         NAPI_ERR_LOG("Invalid arguments! status: %{public}d", status);
409         return undefinedResult;
410     }
411 
412     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
413     if (status == napi_ok && obj != nullptr) {
414         relativePath = obj->albumAssetPtr->GetAlbumRelativePath();
415         status = napi_create_string_utf8(env, relativePath.c_str(), NAPI_AUTO_LENGTH, &jsResult);
416         if (status == napi_ok) {
417             return jsResult;
418         }
419     }
420 
421     return undefinedResult;
422 }
JSGetCoverUri(napi_env env,napi_callback_info info)423 napi_value AlbumNapi::JSGetCoverUri(napi_env env, napi_callback_info info)
424 {
425     napi_status status;
426     napi_value jsResult = nullptr;
427     napi_value undefinedResult = nullptr;
428     AlbumNapi* obj = nullptr;
429     std::string coverUri = "";
430     napi_value thisVar = nullptr;
431 
432     napi_get_undefined(env, &undefinedResult);
433     GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
434     if (status != napi_ok || thisVar == nullptr) {
435         NAPI_ERR_LOG("Invalid arguments! status: %{public}d", status);
436         return undefinedResult;
437     }
438 
439     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
440     if (status == napi_ok && obj != nullptr) {
441         coverUri = obj->albumAssetPtr->GetCoverUri();
442         status = napi_create_string_utf8(env, coverUri.c_str(), NAPI_AUTO_LENGTH, &jsResult);
443         if (status == napi_ok) {
444             return jsResult;
445         }
446     }
447 
448     return undefinedResult;
449 }
450 
JSSetAlbumPath(napi_env env,napi_callback_info info)451 napi_value AlbumNapi::JSSetAlbumPath(napi_env env, napi_callback_info info)
452 {
453     napi_status status;
454     napi_value jsResult = nullptr;
455     size_t argc = ARGS_ONE;
456     napi_value argv[ARGS_ONE] = {0};
457     size_t res = 0;
458     char buffer[PATH_MAX];
459     AlbumNapi* obj = nullptr;
460     napi_value thisVar = nullptr;
461     napi_valuetype valueType = napi_undefined;
462 
463     napi_get_undefined(env, &jsResult);
464     GET_JS_ARGS(env, info, argc, argv, thisVar);
465     NAPI_ASSERT(env, argc == ARGS_ONE, "requires 1 parameter");
466 
467     if (thisVar == nullptr || napi_typeof(env, argv[PARAM0], &valueType) != napi_ok
468         || valueType != napi_string) {
469         NAPI_ERR_LOG("Invalid arguments type! type: %{public}d", valueType);
470         return jsResult;
471     }
472 
473     napi_get_value_string_utf8(env, argv[PARAM0], buffer, PATH_MAX, &res);
474 
475     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
476     if (status == napi_ok && obj != nullptr) {
477         obj->albumAssetPtr->SetAlbumPath(std::string(buffer));
478     }
479 
480     return jsResult;
481 }
482 
JSGetAlbumPath(napi_env env,napi_callback_info info)483 napi_value AlbumNapi::JSGetAlbumPath(napi_env env, napi_callback_info info)
484 {
485     napi_status status;
486     napi_value jsResult = nullptr;
487     napi_value undefinedResult = nullptr;
488     AlbumNapi* obj = nullptr;
489     std::string path = "";
490     napi_value thisVar = nullptr;
491 
492     napi_get_undefined(env, &undefinedResult);
493     GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
494     if (status != napi_ok || thisVar == nullptr) {
495         NAPI_ERR_LOG("Invalid arguments! status: %{public}d", status);
496         return undefinedResult;
497     }
498 
499     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
500     if (status == napi_ok && obj != nullptr) {
501         path = obj->GetAlbumPath();
502         status = napi_create_string_utf8(env, path.c_str(), NAPI_AUTO_LENGTH, &jsResult);
503         if (status == napi_ok) {
504             return jsResult;
505         }
506     }
507 
508     return undefinedResult;
509 }
510 
JSGetAlbumVirtual(napi_env env,napi_callback_info info)511 napi_value AlbumNapi::JSGetAlbumVirtual(napi_env env, napi_callback_info info)
512 {
513     napi_status status;
514     napi_value jsResult = nullptr;
515     napi_value undefinedResult = nullptr;
516     AlbumNapi* obj = nullptr;
517     bool virtualAlbum = false;
518     napi_value thisVar = nullptr;
519 
520     napi_get_undefined(env, &undefinedResult);
521     GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
522     if (status != napi_ok || thisVar == nullptr) {
523         NAPI_ERR_LOG("Invalid arguments! status: %{public}d", status);
524         return undefinedResult;
525     }
526 
527     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
528     if (status == napi_ok && obj != nullptr) {
529         virtualAlbum = obj->albumAssetPtr->GetAlbumVirtual();
530         status = napi_get_boolean(env, virtualAlbum, &jsResult);
531         if (status == napi_ok) {
532             return jsResult;
533         }
534     }
535 
536     return undefinedResult;
537 }
538 
GetFetchOptionsParam(napi_env env,napi_value arg,const AlbumNapiAsyncContext & context,bool & err)539 static void GetFetchOptionsParam(napi_env env, napi_value arg, const AlbumNapiAsyncContext &context, bool &err)
540 {
541     AlbumNapiAsyncContext *asyncContext = const_cast<AlbumNapiAsyncContext *>(&context);
542     CHECK_NULL_PTR_RETURN_VOID(asyncContext, "Async context is null");
543     char buffer[PATH_MAX];
544     size_t res;
545     uint32_t len = 0;
546     napi_value property = nullptr;
547     napi_value stringItem = nullptr;
548     bool present = false;
549     bool boolResult = false;
550 
551     string propertyName = "selections";
552     string tmp = MediaLibraryNapiUtils::GetStringFetchProperty(env, arg, err, present, propertyName);
553     if (!tmp.empty()) {
554         asyncContext->selection = tmp;
555     }
556 
557     propertyName = "order";
558     tmp = MediaLibraryNapiUtils::GetStringFetchProperty(env, arg, err, present, propertyName);
559     if (!tmp.empty()) {
560         asyncContext->order = tmp;
561     }
562 
563     napi_has_named_property(env, arg, "selectionArgs", &present);
564     if (present && napi_get_named_property(env, arg, "selectionArgs", &property) == napi_ok &&
565         napi_is_array(env, property, &boolResult) == napi_ok && boolResult) {
566         napi_get_array_length(env, property, &len);
567         for (size_t i = 0; i < len; i++) {
568             napi_get_element(env, property, i, &stringItem);
569             napi_get_value_string_utf8(env, stringItem, buffer, PATH_MAX, &res);
570             asyncContext->selectionArgs.push_back(std::string(buffer));
571             CHECK_IF_EQUAL(memset_s(buffer, PATH_MAX, 0, sizeof(buffer)) == 0, "Memset for buffer failed");
572         }
573     } else {
574         NAPI_ERR_LOG("Could not get the string argument!");
575         err = true;
576     }
577 }
578 
ConvertJSArgsToNative(napi_env env,size_t argc,const napi_value argv[],AlbumNapiAsyncContext & asyncContext)579 static napi_value ConvertJSArgsToNative(napi_env env, size_t argc, const napi_value argv[],
580     AlbumNapiAsyncContext &asyncContext)
581 {
582     string str = "";
583     std::vector<string> strArr;
584     string order = "";
585     bool err = false;
586     const int32_t refCount = 1;
587     napi_value result;
588     auto context = &asyncContext;
589     CHECK_NULL_PTR_RETURN_UNDEFINED(env, context, result, "Async context is null");
590     NAPI_ASSERT(env, argv != nullptr, "Argument list is empty");
591     if (argc == ARGS_ONE) {
592         napi_valuetype valueType = napi_undefined;
593         if (napi_typeof(env, argv[PARAM0], &valueType) == napi_ok &&
594             (valueType == napi_undefined || valueType == napi_null)) {
595             argc -= 1;
596         }
597     }
598 
599     for (size_t i = PARAM0; i < argc; i++) {
600         napi_valuetype valueType = napi_undefined;
601         napi_typeof(env, argv[i], &valueType);
602 
603         if (i == PARAM0 && valueType == napi_object) {
604             GetFetchOptionsParam(env, argv[PARAM0], asyncContext, err);
605             if (err) {
606                 NAPI_ASSERT(env, false, "type mismatch");
607             }
608         } else if (i == PARAM0 && valueType == napi_function) {
609             napi_create_reference(env, argv[i], refCount, &context->callbackRef);
610             break;
611         } else if (i == PARAM1 && valueType == napi_function) {
612             napi_create_reference(env, argv[i], refCount, &context->callbackRef);
613             break;
614         } else {
615             NAPI_ASSERT(env, false, "type mismatch");
616         }
617     }
618 
619     // Return true napi_value if params are successfully obtained
620     napi_get_boolean(env, true, &result);
621     return result;
622 }
ConvertCommitJSArgsToNative(napi_env env,size_t argc,const napi_value argv[],AlbumNapiAsyncContext & asyncContext)623 static napi_value ConvertCommitJSArgsToNative(napi_env env, size_t argc, const napi_value argv[],
624     AlbumNapiAsyncContext &asyncContext)
625 {
626     string str = "";
627     vector<string> strArr;
628     string order = "";
629     bool err = false;
630     const int32_t refCount = 1;
631     napi_value result;
632     auto context = &asyncContext;
633     CHECK_NULL_PTR_RETURN_UNDEFINED(env, context, result, "Async context is null");
634     NAPI_ASSERT(env, argv != nullptr, "Argument list is empty");
635 
636     for (size_t i = PARAM0; i < argc; i++) {
637         napi_valuetype valueType = napi_undefined;
638         napi_typeof(env, argv[i], &valueType);
639 
640         if (i == PARAM0 && valueType == napi_object) {
641             GetFetchOptionsParam(env, argv[PARAM0], asyncContext, err);
642             if (err) {
643                 NAPI_ERR_LOG("fetch options retrieval failed. err %{public}d", err);
644                 NAPI_ASSERT(env, false, "type mismatch");
645             }
646         } else if (i == PARAM0 && valueType == napi_function) {
647             napi_create_reference(env, argv[i], refCount, &context->callbackRef);
648             break;
649         } else if (i == PARAM1 && valueType == napi_function) {
650             napi_create_reference(env, argv[i], refCount, &context->callbackRef);
651             break;
652         } else {
653             NAPI_ASSERT(env, false, "type mismatch");
654         }
655     }
656 
657     // Return true napi_value if params are successfully obtained
658     napi_get_boolean(env, true, &result);
659     return result;
660 }
661 
662 #ifdef MEDIALIBRARY_COMPATIBILITY
UpdateCompatAlbumSelection(AlbumNapiAsyncContext * context)663 static void UpdateCompatAlbumSelection(AlbumNapiAsyncContext *context)
664 {
665     PhotoAlbumSubType subType = context->objectPtr->GetAlbumSubType();
666     string filterClause;
667     switch (subType) {
668         case PhotoAlbumSubType::CAMERA: {
669             static const string CAMERA_FILTER = PhotoColumn::PHOTO_SUBTYPE + "=" +
670                 to_string(static_cast<int32_t>(PhotoSubType::CAMERA)) + " AND " + MediaColumn::ASSETS_QUERY_FILTER;
671             filterClause = CAMERA_FILTER;
672             break;
673         }
674         case PhotoAlbumSubType::SCREENSHOT: {
675             static const string SCREENSHOT_FILTER = PhotoColumn::PHOTO_SUBTYPE + "=" +
676                 to_string(static_cast<int32_t>(PhotoSubType::SCREENSHOT)) + " AND " + MediaColumn::ASSETS_QUERY_FILTER;
677             filterClause = SCREENSHOT_FILTER;
678             break;
679         }
680         case PhotoAlbumSubType::FAVORITE: {
681             static const string FAVORITE_FILTER = PhotoColumn::MEDIA_IS_FAV + " = 1" + " AND " +
682                 MediaColumn::ASSETS_QUERY_FILTER;
683             filterClause = FAVORITE_FILTER;
684             break;
685         }
686         case PhotoAlbumSubType::TRASH: {
687             static const string TRASH_FILTER =
688                 PhotoColumn::MEDIA_DATE_TRASHED + " > 0 AND " + MEDIA_DATA_DB_IS_TRASH + " <> " +
689                 to_string(static_cast<int32_t>(TRASHED_DIR_CHILD));
690             filterClause = TRASH_FILTER;
691             break;
692         }
693         default: {
694             NAPI_ERR_LOG("Album subtype not support for compatibility: %{public}d", subType);
695             context->SaveError(-EINVAL);
696             return;
697         }
698     }
699     if (!context->selection.empty()) {
700         context->selection = filterClause + " AND (" + context->selection + ")";
701     } else {
702         context->selection = filterClause;
703     }
704     MediaLibraryNapi::ReplaceSelection(context->selection, context->selectionArgs,
705         MEDIA_DATA_DB_RELATIVE_PATH, MEDIA_DATA_DB_RELATIVE_PATH);
706 }
707 #endif
708 
UpdateSelection(AlbumNapiAsyncContext * context)709 static void UpdateSelection(AlbumNapiAsyncContext *context)
710 {
711     if (context->resultNapiType == ResultNapiType::TYPE_USERFILE_MGR ||
712         context->resultNapiType == ResultNapiType::TYPE_PHOTOACCESS_HELPER) {
713         context->predicates.EqualTo(MEDIA_DATA_DB_DATE_TRASHED, 0);
714         context->predicates.NotEqualTo(MEDIA_DATA_DB_MEDIA_TYPE, MEDIA_TYPE_ALBUM);
715         context->predicates.EqualTo(MEDIA_DATA_DB_BUCKET_ID, context->objectPtr->GetAlbumId());
716         context->predicates.EqualTo(MediaColumn::MEDIA_TIME_PENDING, to_string(0));
717         context->predicates.EqualTo(PhotoColumn::PHOTO_IS_TEMP, to_string(0));
718         context->predicates.EqualTo(PhotoColumn::PHOTO_BURST_COVER_LEVEL,
719             to_string(static_cast<int32_t>(BurstCoverLevelType::COVER)));
720         MediaLibraryNapiUtils::UpdateMediaTypeSelections(context);
721     } else {
722 #ifdef MEDIALIBRARY_COMPATIBILITY
723         UpdateCompatAlbumSelection(context);
724 #else
725         string trashPrefix = MEDIA_DATA_DB_DATE_TRASHED + " = ? ";
726         MediaLibraryNapiUtils::AppendFetchOptionSelection(context->selection, trashPrefix);
727         context->selectionArgs.emplace_back("0");
728 
729         string prefix = MEDIA_DATA_DB_MEDIA_TYPE + " <> ? ";
730         MediaLibraryNapiUtils::AppendFetchOptionSelection(context->selection, prefix);
731         context->selectionArgs.emplace_back(to_string(MEDIA_TYPE_ALBUM));
732 
733         string idPrefix = MEDIA_DATA_DB_BUCKET_ID + " = ? ";
734         MediaLibraryNapiUtils::AppendFetchOptionSelection(context->selection, idPrefix);
735         context->selectionArgs.emplace_back(std::to_string(context->objectPtr->GetAlbumId()));
736 #endif
737     }
738 }
739 
GetFileAssetsNative(napi_env env,void * data)740 static void GetFileAssetsNative(napi_env env, void *data)
741 {
742     MediaLibraryTracer tracer;
743     tracer.Start("GetFileAssetsNative");
744 
745     AlbumNapiAsyncContext *context = static_cast<AlbumNapiAsyncContext*>(data);
746 
747     UpdateSelection(context);
748     MediaLibraryNapiUtils::FixSpecialDateType(context->selection);
749     context->predicates.SetWhereClause(context->selection);
750     context->predicates.SetWhereArgs(context->selectionArgs);
751     context->predicates.SetOrder(context->order);
752 
753     if (context->resultNapiType == ResultNapiType::TYPE_MEDIALIBRARY) {
754         context->fetchColumn = FILE_ASSET_COLUMNS;
755     } else {
756         context->fetchColumn.push_back(MEDIA_DATA_DB_ID);
757         context->fetchColumn.push_back(MEDIA_DATA_DB_NAME);
758         context->fetchColumn.push_back(MEDIA_DATA_DB_MEDIA_TYPE);
759     }
760 
761     string queryUri = MEDIALIBRARY_DATA_ABILITY_PREFIX +
762         (MediaFileUtils::GetNetworkIdFromUri(context->objectPtr->GetAlbumUri())) + MEDIALIBRARY_DATA_URI_IDENTIFIER;
763     NAPI_DEBUG_LOG("queryUri is = %{private}s", queryUri.c_str());
764     Uri uri(queryUri);
765     int errCode = 0;
766     std::shared_ptr<OHOS::DataShare::DataShareResultSet> resultSet =
767         UserFileClient::Query(uri, context->predicates, context->fetchColumn, errCode);
768     if (resultSet == nullptr) {
769         NAPI_ERR_LOG("GetFileAssetsNative called, UserFileClient::Query errorCode is = %{public}d", errCode);
770         return;
771     }
772     context->fetchResult = std::make_unique<FetchResult<FileAsset>>(move(resultSet));
773     context->fetchResult->SetNetworkId(MediaFileUtils::GetNetworkIdFromUri(context->objectPtr->GetAlbumUri()));
774     if (context->resultNapiType == ResultNapiType::TYPE_USERFILE_MGR ||
775         context->resultNapiType == ResultNapiType::TYPE_PHOTOACCESS_HELPER) {
776         context->fetchResult->SetResultNapiType(context->resultNapiType);
777     }
778 }
779 
JSGetFileAssetsCompleteCallback(napi_env env,napi_status status,void * data)780 static void JSGetFileAssetsCompleteCallback(napi_env env, napi_status status, void *data)
781 {
782     MediaLibraryTracer tracer;
783     tracer.Start("JSGetFileAssetsCompleteCallback");
784 
785     AlbumNapiAsyncContext *context = static_cast<AlbumNapiAsyncContext*>(data);
786     CHECK_NULL_PTR_RETURN_VOID(context, "Async context is null");
787 
788     std::unique_ptr<JSAsyncContextOutput> jsContext = std::make_unique<JSAsyncContextOutput>();
789     jsContext->status = false;
790     if (context->fetchResult != nullptr) {
791         if (context->fetchResult->GetCount() < 0) {
792             napi_get_undefined(env, &jsContext->data);
793             MediaLibraryNapiUtils::CreateNapiErrorObject(env, jsContext->error, ERR_MEM_ALLOCATION,
794                                                          "find no data by options");
795         } else {
796             napi_value fetchRes = FetchFileResultNapi::CreateFetchFileResult(env, move(context->fetchResult));
797             if (fetchRes == nullptr) {
798                 NAPI_ERR_LOG("Failed to get file asset napi object");
799                 napi_get_undefined(env, &jsContext->data);
800                 MediaLibraryNapiUtils::CreateNapiErrorObject(env, jsContext->error, ERR_MEM_ALLOCATION,
801                     "Failed to create js object for FetchFileResult");
802             } else {
803                 jsContext->data = fetchRes;
804                 napi_get_undefined(env, &jsContext->error);
805                 jsContext->status = true;
806             }
807         }
808     } else {
809         NAPI_ERR_LOG("No fetch file result found!");
810         napi_get_undefined(env, &jsContext->data);
811         MediaLibraryNapiUtils::CreateNapiErrorObject(env, jsContext->error, ERR_INVALID_OUTPUT,
812                                                      "Failed to obtain fetchFileResult from DB");
813     }
814 
815     tracer.Finish();
816     if (context->work != nullptr) {
817         MediaLibraryNapiUtils::InvokeJSAsyncMethod(env, context->deferred, context->callbackRef,
818                                                    context->work, *jsContext);
819     }
820     delete context;
821 }
822 
CommitModifyNative(napi_env env,void * data)823 static void CommitModifyNative(napi_env env, void *data)
824 {
825     MediaLibraryTracer tracer;
826     tracer.Start("CommitModifyNative");
827 
828     auto *context = static_cast<AlbumNapiAsyncContext*>(data);
829     auto objectPtr = context->objectPtr;
830     if (MediaFileUtils::CheckAlbumName(objectPtr->GetAlbumName()) < 0) {
831         context->error = JS_E_DISPLAYNAME;
832         NAPI_ERR_LOG("album name invalid = %{private}s", objectPtr->GetAlbumName().c_str());
833         return;
834     }
835 #ifdef MEDIALIBRARY_COMPATIBILITY
836     context->changedRows = 0;
837 #else
838     DataSharePredicates predicates;
839     DataShareValuesBucket valuesBucket;
840     valuesBucket.Put(MEDIA_DATA_DB_TITLE, objectPtr->GetAlbumName());
841     predicates.SetWhereClause(MEDIA_DATA_DB_ID + " = ? ");
842     predicates.SetWhereArgs({ std::to_string(objectPtr->GetAlbumId()) });
843 
844     string updateUri = MEDIALIBRARY_DATA_URI + "/" +
845         MEDIA_ALBUMOPRN + "/" + MEDIA_ALBUMOPRN_MODIFYALBUM + "/" + std::to_string(objectPtr->GetAlbumId());
846     Uri uri(updateUri);
847     int changedRows = UserFileClient::Update(uri, predicates, valuesBucket);
848     if (changedRows > 0) {
849         DataSharePredicates filePredicates;
850         DataShareValuesBucket fileValuesBucket;
851         fileValuesBucket.Put(MEDIA_DATA_DB_BUCKET_NAME, objectPtr->GetAlbumName());
852         filePredicates.SetWhereClause(MEDIA_DATA_DB_BUCKET_ID + " = ? ");
853         filePredicates.SetWhereArgs({ std::to_string(objectPtr->GetAlbumId()) });
854 
855         string fileUriStr = MEDIALIBRARY_DATA_URI;
856         Uri fileUri(fileUriStr);
857         changedRows = UserFileClient::Update(fileUri, filePredicates, fileValuesBucket);
858     }
859     context->SaveError(changedRows);
860     context->changedRows = changedRows;
861 #endif
862 }
863 
JSCommitModifyCompleteCallback(napi_env env,napi_status status,void * data)864 static void JSCommitModifyCompleteCallback(napi_env env, napi_status status, void *data)
865 {
866     MediaLibraryTracer tracer;
867     tracer.Start("JSCommitModifyCompleteCallback");
868 
869     AlbumNapiAsyncContext *context = static_cast<AlbumNapiAsyncContext*>(data);
870     CHECK_NULL_PTR_RETURN_VOID(context, "Async context is null");
871     std::unique_ptr<JSAsyncContextOutput> jsContext = std::make_unique<JSAsyncContextOutput>();
872     jsContext->status = false;
873     if (context->error == ERR_DEFAULT) {
874         napi_create_int32(env, context->changedRows, &jsContext->data);
875         napi_get_undefined(env, &jsContext->error);
876         jsContext->status = true;
877         auto contextUri = make_unique<Uri>(MEDIALIBRARY_ALBUM_URI);
878         UserFileClient::NotifyChange(*contextUri);
879     } else {
880         napi_get_undefined(env, &jsContext->data);
881         context->HandleError(env, jsContext->error);
882     }
883 
884     tracer.Finish();
885     if (context->work != nullptr) {
886         MediaLibraryNapiUtils::InvokeJSAsyncMethod(env, context->deferred, context->callbackRef,
887                                                    context->work, *jsContext);
888     }
889 
890     delete context;
891 }
JSGetAlbumFileAssets(napi_env env,napi_callback_info info)892 napi_value AlbumNapi::JSGetAlbumFileAssets(napi_env env, napi_callback_info info)
893 {
894     napi_status status;
895     napi_value result = nullptr;
896     size_t argc = ARGS_TWO;
897     napi_value argv[ARGS_TWO] = {0};
898     napi_value thisVar = nullptr;
899 
900     MediaLibraryTracer tracer;
901     tracer.Start("JSGetAlbumFileAssets");
902 
903     GET_JS_ARGS(env, info, argc, argv, thisVar);
904     NAPI_ASSERT(env, ((argc == ARGS_ZERO) || (argc == ARGS_ONE) || (argc == ARGS_TWO)),
905                 "requires 2 parameter maximum");
906     napi_get_undefined(env, &result);
907 
908     std::unique_ptr<AlbumNapiAsyncContext> asyncContext = std::make_unique<AlbumNapiAsyncContext>();
909     asyncContext->resultNapiType = ResultNapiType::TYPE_MEDIALIBRARY;
910     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&asyncContext->objectInfo));
911     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
912         result = ConvertJSArgsToNative(env, argc, argv, *asyncContext);
913         CHECK_NULL_PTR_RETURN_UNDEFINED(env, result, result, "Failed to obtain arguments");
914         asyncContext->objectPtr = asyncContext->objectInfo->albumAssetPtr;
915         CHECK_NULL_PTR_RETURN_UNDEFINED(env, asyncContext->objectPtr, result, "AlbumAsset is nullptr");
916 
917         result = MediaLibraryNapiUtils::NapiCreateAsyncWork(env, asyncContext, "JSGetAlbumFileAssets",
918             GetFileAssetsNative, JSGetFileAssetsCompleteCallback);
919     }
920 
921     return result;
922 }
JSCommitModify(napi_env env,napi_callback_info info)923 napi_value AlbumNapi::JSCommitModify(napi_env env, napi_callback_info info)
924 {
925     napi_status status;
926     napi_value result = nullptr;
927     size_t argc = ARGS_ONE;
928     napi_value argv[ARGS_ONE] = {0};
929     napi_value thisVar = nullptr;
930 
931     MediaLibraryTracer tracer;
932     tracer.Start("JSCommitModify");
933 
934     GET_JS_ARGS(env, info, argc, argv, thisVar);
935     NAPI_ASSERT(env, (argc == ARGS_ZERO || argc == ARGS_ONE), "requires 1 parameter maximum");
936     napi_get_undefined(env, &result);
937 
938     std::unique_ptr<AlbumNapiAsyncContext> asyncContext = std::make_unique<AlbumNapiAsyncContext>();
939     CHECK_NULL_PTR_RETURN_UNDEFINED(env, asyncContext, result, "asyncContext context is null");
940     asyncContext->resultNapiType = ResultNapiType::TYPE_MEDIALIBRARY;
941     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&asyncContext->objectInfo));
942     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
943         result = ConvertCommitJSArgsToNative(env, argc, argv, *asyncContext);
944         CHECK_NULL_PTR_RETURN_UNDEFINED(env, result, result, "JSCommitModify fail ");
945         asyncContext->objectPtr = asyncContext->objectInfo->albumAssetPtr;
946         CHECK_NULL_PTR_RETURN_UNDEFINED(env, asyncContext->objectPtr, result, "AlbumAsset is nullptr");
947 
948         result = MediaLibraryNapiUtils::NapiCreateAsyncWork(env, asyncContext, "JSCommitModify", CommitModifyNative,
949             JSCommitModifyCompleteCallback);
950     }
951 
952     return result;
953 }
954 
UserFileMgrGetAssets(napi_env env,napi_callback_info info)955 napi_value AlbumNapi::UserFileMgrGetAssets(napi_env env, napi_callback_info info)
956 {
957     napi_value ret = nullptr;
958     unique_ptr<AlbumNapiAsyncContext> asyncContext = make_unique<AlbumNapiAsyncContext>();
959     CHECK_NULL_PTR_RETURN_UNDEFINED(env, asyncContext, ret, "asyncContext context is null");
960 
961     asyncContext->mediaTypes.push_back(MEDIA_TYPE_IMAGE);
962     asyncContext->mediaTypes.push_back(MEDIA_TYPE_VIDEO);
963     CHECK_ARGS(env, MediaLibraryNapiUtils::ParseAssetFetchOptCallback(env, info, asyncContext),
964         JS_ERR_PARAMETER_INVALID);
965     asyncContext->resultNapiType = ResultNapiType::TYPE_USERFILE_MGR;
966     asyncContext->objectPtr = asyncContext->objectInfo->albumAssetPtr;
967     CHECK_NULL_PTR_RETURN_UNDEFINED(env, asyncContext->objectPtr, ret, "AlbumAsset is nullptr");
968 
969     return MediaLibraryNapiUtils::NapiCreateAsyncWork(env, asyncContext, "UserFileMgrGetAssets", GetFileAssetsNative,
970         JSGetFileAssetsCompleteCallback);
971 }
972 
UserFileMgrCommitModify(napi_env env,napi_callback_info info)973 napi_value AlbumNapi::UserFileMgrCommitModify(napi_env env, napi_callback_info info)
974 {
975     MediaLibraryTracer tracer;
976     tracer.Start("UserFileMgrCommitModify");
977 
978     napi_value ret = nullptr;
979     unique_ptr<AlbumNapiAsyncContext> asyncContext = make_unique<AlbumNapiAsyncContext>();
980     CHECK_NULL_PTR_RETURN_UNDEFINED(env, asyncContext, ret, "asyncContext context is null");
981     asyncContext->resultNapiType = ResultNapiType::TYPE_USERFILE_MGR;
982     CHECK_ARGS(env, MediaLibraryNapiUtils::ParseArgsOnlyCallBack(env, info, asyncContext), JS_ERR_PARAMETER_INVALID);
983     asyncContext->objectPtr = asyncContext->objectInfo->albumAssetPtr;
984     CHECK_NULL_PTR_RETURN_UNDEFINED(env, asyncContext->objectPtr, ret, "AlbumAsset is nullptr");
985 
986     return MediaLibraryNapiUtils::NapiCreateAsyncWork(env, asyncContext, "UserFileMgrCommitModify", CommitModifyNative,
987         JSCommitModifyCompleteCallback);
988 }
989 
PhotoAccessHelperGetAssets(napi_env env,napi_callback_info info)990 napi_value AlbumNapi::PhotoAccessHelperGetAssets(napi_env env, napi_callback_info info)
991 {
992     napi_value ret = nullptr;
993     unique_ptr<AlbumNapiAsyncContext> asyncContext = make_unique<AlbumNapiAsyncContext>();
994     CHECK_NULL_PTR_RETURN_UNDEFINED(env, asyncContext, ret, "asyncContext context is null");
995 
996     asyncContext->mediaTypes.push_back(MEDIA_TYPE_IMAGE);
997     asyncContext->mediaTypes.push_back(MEDIA_TYPE_VIDEO);
998     CHECK_ARGS(env, MediaLibraryNapiUtils::ParseAssetFetchOptCallback(env, info, asyncContext),
999         JS_ERR_PARAMETER_INVALID);
1000     asyncContext->resultNapiType = ResultNapiType::TYPE_PHOTOACCESS_HELPER;
1001     asyncContext->objectPtr = asyncContext->objectInfo->albumAssetPtr;
1002     CHECK_NULL_PTR_RETURN_UNDEFINED(env, asyncContext->objectPtr, ret, "AlbumAsset is nullptr");
1003 
1004     return MediaLibraryNapiUtils::NapiCreateAsyncWork(env, asyncContext, "UserFileMgrGetAssets", GetFileAssetsNative,
1005         JSGetFileAssetsCompleteCallback);
1006 }
1007 
PhotoAccessHelperCommitModify(napi_env env,napi_callback_info info)1008 napi_value AlbumNapi::PhotoAccessHelperCommitModify(napi_env env, napi_callback_info info)
1009 {
1010     MediaLibraryTracer tracer;
1011     tracer.Start("UserFileMgrCommitModify");
1012 
1013     napi_value ret = nullptr;
1014     unique_ptr<AlbumNapiAsyncContext> asyncContext = make_unique<AlbumNapiAsyncContext>();
1015     CHECK_NULL_PTR_RETURN_UNDEFINED(env, asyncContext, ret, "asyncContext context is null");
1016     asyncContext->resultNapiType = ResultNapiType::TYPE_PHOTOACCESS_HELPER;
1017     CHECK_ARGS(env, MediaLibraryNapiUtils::ParseArgsOnlyCallBack(env, info, asyncContext), JS_ERR_PARAMETER_INVALID);
1018     asyncContext->objectPtr = asyncContext->objectInfo->albumAssetPtr;
1019     CHECK_NULL_PTR_RETURN_UNDEFINED(env, asyncContext->objectPtr, ret, "AlbumAsset is nullptr");
1020 
1021     return MediaLibraryNapiUtils::NapiCreateAsyncWork(env, asyncContext, "UserFileMgrCommitModify", CommitModifyNative,
1022         JSCommitModifyCompleteCallback);
1023 }
1024 } // namespace Media
1025 } // namespace OHOS
1026