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