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