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