• 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 "SmartAlbumNapi"
16 
17 #include "smart_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 
24 using OHOS::HiviewDFX::HiLog;
25 using OHOS::HiviewDFX::HiLogLabel;
26 
27 namespace OHOS {
28 namespace Media {
29 using namespace std;
30 thread_local napi_ref SmartAlbumNapi::sConstructor_ = nullptr;
31 thread_local SmartAlbumAsset *SmartAlbumNapi::sAlbumData_ = nullptr;
32 using CompleteCallback = napi_async_complete_callback;
33 
34 thread_local napi_ref SmartAlbumNapi::userFileMgrConstructor_ = nullptr;
35 
SmartAlbumNapi()36 SmartAlbumNapi::SmartAlbumNapi()
37     : env_(nullptr) {}
38 
39 SmartAlbumNapi::~SmartAlbumNapi() = default;
40 
SmartAlbumNapiDestructor(napi_env env,void * nativeObject,void * finalize_hint)41 void SmartAlbumNapi::SmartAlbumNapiDestructor(napi_env env, void *nativeObject, void *finalize_hint)
42 {
43     SmartAlbumNapi *album = reinterpret_cast<SmartAlbumNapi*>(nativeObject);
44     if (album != nullptr) {
45         delete album;
46         album = nullptr;
47     }
48 }
49 
Init(napi_env env,napi_value exports)50 napi_value SmartAlbumNapi::Init(napi_env env, napi_value exports)
51 {
52     NAPI_DEBUG_LOG("SmartAlbumNapi::Init");
53     napi_status status;
54     napi_value ctorObj;
55     int32_t refCount = 1;
56 
57     napi_property_descriptor album_props[] = {
58         DECLARE_NAPI_GETTER("albumId", JSGetSmartAlbumId),
59         DECLARE_NAPI_GETTER("albumUri", JSGetSmartAlbumUri),
60         DECLARE_NAPI_GETTER_SETTER("albumName", JSGetSmartAlbumName, JSSmartAlbumNameSetter),
61         DECLARE_NAPI_GETTER("albumTag", JSGetSmartAlbumTag),
62         DECLARE_NAPI_GETTER("size", JSGetSmartAlbumCapacity),
63         DECLARE_NAPI_GETTER("categoryId", JSGetSmartAlbumCategoryId),
64         DECLARE_NAPI_GETTER("categoryName", JSGetSmartAlbumCategoryName),
65         DECLARE_NAPI_GETTER("coverUri", JSGetSmartAlbumCoverUri),
66         DECLARE_NAPI_FUNCTION("commitModify", JSCommitModify),
67         DECLARE_NAPI_FUNCTION("addAsset", JSAddAsset),
68         DECLARE_NAPI_FUNCTION("removeAsset", JSRemoveAsset),
69         DECLARE_NAPI_FUNCTION("getFileAssets", JSGetSmartAlbumFileAssets)
70     };
71 
72     status = napi_define_class(env, SMART_ALBUM_NAPI_CLASS_NAME.c_str(), NAPI_AUTO_LENGTH,
73                                SmartAlbumNapiConstructor, nullptr,
74                                sizeof(album_props) / sizeof(album_props[PARAM0]),
75                                album_props, &ctorObj);
76     if (status == napi_ok) {
77         status = napi_create_reference(env, ctorObj, refCount, &sConstructor_);
78         if (status == napi_ok) {
79             status = napi_set_named_property(env, exports, SMART_ALBUM_NAPI_CLASS_NAME.c_str(), ctorObj);
80             if (status == napi_ok) {
81                 return exports;
82             }
83         }
84     }
85     NAPI_DEBUG_LOG("SmartAlbumNapi::Init nullptr, status: %{public}d", status);
86     return nullptr;
87 }
88 
UserFileMgrInit(napi_env env,napi_value exports)89 napi_value SmartAlbumNapi::UserFileMgrInit(napi_env env, napi_value exports)
90 {
91     NapiClassInfo info = {
92         .name = USERFILEMGR_SMART_ALBUM_NAPI_CLASS_NAME,
93         .ref = &userFileMgrConstructor_,
94         .constructor = SmartAlbumNapiConstructor,
95         .props = {
96             DECLARE_NAPI_GETTER_SETTER("albumName", JSGetSmartAlbumName, JSSmartAlbumNameSetter),
97             DECLARE_NAPI_GETTER("albumUri", JSGetSmartAlbumUri),
98             DECLARE_NAPI_GETTER("dateModified", JSGetSmartAlbumDateModified),
99             DECLARE_NAPI_GETTER("count", JSGetSmartAlbumCapacity),
100             DECLARE_NAPI_GETTER("coverUri", JSGetSmartAlbumCoverUri),
101             DECLARE_NAPI_FUNCTION("getPhotoAssets", UserFileMgrGetAssets),
102             DECLARE_NAPI_FUNCTION("delete", UserFileMgrDeleteAsset),
103             DECLARE_NAPI_FUNCTION("recover", UserFileMgrRecoverAsset),
104         }
105     };
106 
107     MediaLibraryNapiUtils::NapiDefineClass(env, exports, info);
108     return exports;
109 }
110 
SetSmartAlbumNapiProperties()111 void SmartAlbumNapi::SetSmartAlbumNapiProperties()
112 {
113     smartAlbumAssetPtr = std::shared_ptr<SmartAlbumAsset>(sAlbumData_);
114     NAPI_INFO_LOG("SetSmartAlbumNapiProperties name = %{public}s",
115         smartAlbumAssetPtr->GetAlbumName().c_str());
116 }
117 
118 // Constructor callback
SmartAlbumNapiConstructor(napi_env env,napi_callback_info info)119 napi_value SmartAlbumNapi::SmartAlbumNapiConstructor(napi_env env, napi_callback_info info)
120 {
121     napi_status status;
122     napi_value result = nullptr;
123     napi_value thisVar = nullptr;
124     napi_get_undefined(env, &result);
125     GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
126     if (status == napi_ok && thisVar != nullptr) {
127         std::unique_ptr<SmartAlbumNapi> obj = std::make_unique<SmartAlbumNapi>();
128         if (obj != nullptr) {
129             obj->env_ = env;
130             if (sAlbumData_ != nullptr) {
131                 obj->SetSmartAlbumNapiProperties();
132             }
133             status = napi_wrap(env, thisVar, reinterpret_cast<void*>(obj.get()),
134                                SmartAlbumNapi::SmartAlbumNapiDestructor, nullptr, nullptr);
135             if (status == napi_ok) {
136                 obj.release();
137                 return thisVar;
138             } else {
139                 NAPI_ERR_LOG("Failure wrapping js to native napi, status: %{public}d", status);
140             }
141         }
142     }
143 
144     return result;
145 }
146 
CreateSmartAlbumNapi(napi_env env,unique_ptr<SmartAlbumAsset> & albumData)147 napi_value SmartAlbumNapi::CreateSmartAlbumNapi(napi_env env, unique_ptr<SmartAlbumAsset> &albumData)
148 {
149     if (albumData == nullptr) {
150         return nullptr;
151     }
152 
153     napi_value constructor;
154     napi_ref constructorRef = (albumData->GetTypeMask().empty()) ? (sConstructor_) : (userFileMgrConstructor_);
155     NAPI_CALL(env, napi_get_reference_value(env, constructorRef, &constructor));
156 
157     napi_value result = nullptr;
158     sAlbumData_ = albumData.release();
159     NAPI_CALL(env, napi_new_instance(env, constructor, 0, nullptr, &result));
160     sAlbumData_ = nullptr;
161     return result;
162 }
163 
GetSmartAlbumName() const164 std::string SmartAlbumNapi::GetSmartAlbumName() const
165 {
166     return smartAlbumAssetPtr->GetAlbumName();
167 }
168 
GetAlbumPrivateType() const169 int32_t SmartAlbumNapi::GetAlbumPrivateType() const
170 {
171     return smartAlbumAssetPtr->GetAlbumPrivateType();
172 }
173 
GetSmartAlbumUri() const174 std::string SmartAlbumNapi::GetSmartAlbumUri() const
175 {
176     return smartAlbumAssetPtr->GetAlbumUri();
177 }
178 
GetSmartAlbumId() const179 int32_t SmartAlbumNapi::GetSmartAlbumId() const
180 {
181     return smartAlbumAssetPtr->GetAlbumId();
182 }
SetAlbumCapacity(int32_t albumCapacity)183 void SmartAlbumNapi::SetAlbumCapacity(int32_t albumCapacity)
184 {
185     smartAlbumAssetPtr->SetAlbumCapacity(albumCapacity);
186 }
187 
GetNetworkId() const188 std::string SmartAlbumNapi::GetNetworkId() const
189 {
190     return MediaFileUtils::GetNetworkIdFromUri(GetSmartAlbumUri());
191 }
192 
GetTypeMask() const193 std::string SmartAlbumNapi::GetTypeMask() const
194 {
195     return smartAlbumAssetPtr->GetTypeMask();
196 }
197 
JSGetSmartAlbumId(napi_env env,napi_callback_info info)198 napi_value SmartAlbumNapi::JSGetSmartAlbumId(napi_env env, napi_callback_info info)
199 {
200     napi_status status;
201     napi_value jsResult = nullptr;
202     napi_value undefinedResult = nullptr;
203     SmartAlbumNapi* obj = nullptr;
204     int32_t id;
205     napi_value thisVar = nullptr;
206 
207     napi_get_undefined(env, &undefinedResult);
208     GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
209     if ((status != napi_ok) || (thisVar == nullptr)) {
210         NAPI_ERR_LOG("Invalid arguments! status: %{public}d", status);
211         return undefinedResult;
212     }
213 
214     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
215     if ((status == napi_ok) && (obj != nullptr)) {
216         id = obj->GetSmartAlbumId();
217         status = napi_create_int32(env, id, &jsResult);
218         if (status == napi_ok) {
219             return jsResult;
220         }
221     }
222 
223     return undefinedResult;
224 }
225 
JSGetSmartAlbumName(napi_env env,napi_callback_info info)226 napi_value SmartAlbumNapi::JSGetSmartAlbumName(napi_env env, napi_callback_info info)
227 {
228     napi_status status;
229     napi_value jsResult = nullptr;
230     napi_value undefinedResult = nullptr;
231     SmartAlbumNapi* obj = nullptr;
232     std::string name = "";
233     napi_value thisVar = nullptr;
234     napi_get_undefined(env, &undefinedResult);
235     GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
236     if ((status != napi_ok) || (thisVar == nullptr)) {
237         NAPI_ERR_LOG("Invalid arguments! status: %{public}d", status);
238         return undefinedResult;
239     }
240     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
241     if ((status == napi_ok) && (obj != nullptr)) {
242         name = obj->GetSmartAlbumName();
243         NAPI_DEBUG_LOG("JSGetSmartAlbumName name = %{public}s", name.c_str());
244         status = napi_create_string_utf8(env, name.c_str(), NAPI_AUTO_LENGTH, &jsResult);
245         if (status == napi_ok) {
246             return jsResult;
247         }
248     }
249 
250     return undefinedResult;
251 }
252 
JSSmartAlbumNameSetter(napi_env env,napi_callback_info info)253 napi_value SmartAlbumNapi::JSSmartAlbumNameSetter(napi_env env, napi_callback_info info)
254 {
255     napi_status status;
256     napi_value jsResult = nullptr;
257     size_t argc = ARGS_ONE;
258     napi_value argv[ARGS_ONE] = {0};
259     size_t res = 0;
260     char buffer[FILENAME_MAX];
261     SmartAlbumNapi* obj = nullptr;
262     napi_value thisVar = nullptr;
263     napi_valuetype valueType = napi_undefined;
264 
265     napi_get_undefined(env, &jsResult);
266     GET_JS_ARGS(env, info, argc, argv, thisVar);
267     NAPI_ASSERT(env, argc == ARGS_ONE, "requires 1 parameter");
268 
269     if (thisVar == nullptr || napi_typeof(env, argv[PARAM0], &valueType) != napi_ok
270         || valueType != napi_string) {
271         NAPI_ERR_LOG("Invalid arguments type! valueType: %{public}d", valueType);
272         return jsResult;
273     }
274 
275     napi_get_value_string_utf8(env, argv[PARAM0], buffer, FILENAME_MAX, &res);
276 
277     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
278     if (status == napi_ok && obj != nullptr) {
279         obj->smartAlbumAssetPtr->SetAlbumName(std::string(buffer));
280     }
281 
282     return jsResult;
283 }
284 
JSGetSmartAlbumTag(napi_env env,napi_callback_info info)285 napi_value SmartAlbumNapi::JSGetSmartAlbumTag(napi_env env, napi_callback_info info)
286 {
287     napi_status status;
288     napi_value jsResult = nullptr;
289     napi_value undefinedResult = nullptr;
290     SmartAlbumNapi* obj = nullptr;
291     std::string albumTag = "";
292     napi_value thisVar = nullptr;
293 
294     napi_get_undefined(env, &undefinedResult);
295     GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
296     if (status != napi_ok || thisVar == nullptr) {
297         NAPI_ERR_LOG("Invalid arguments! status: %{public}d", status);
298         return undefinedResult;
299     }
300 
301     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
302     if (status == napi_ok && obj != nullptr) {
303         albumTag = obj->smartAlbumAssetPtr->GetAlbumTag();
304         status = napi_create_string_utf8(env, albumTag.c_str(), NAPI_AUTO_LENGTH, &jsResult);
305         if (status == napi_ok) {
306             return jsResult;
307         }
308     }
309 
310     return undefinedResult;
311 }
312 
JSGetSmartAlbumCapacity(napi_env env,napi_callback_info info)313 napi_value SmartAlbumNapi::JSGetSmartAlbumCapacity(napi_env env, napi_callback_info info)
314 {
315     napi_status status;
316     napi_value jsResult = nullptr;
317     napi_value undefinedResult = nullptr;
318     SmartAlbumNapi* obj = nullptr;
319     int32_t albumCapacity;
320     napi_value thisVar = nullptr;
321 
322     napi_get_undefined(env, &undefinedResult);
323     GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
324     if (status != napi_ok || thisVar == nullptr) {
325         NAPI_ERR_LOG("Invalid arguments! status: %{public}d", status);
326         return undefinedResult;
327     }
328 
329     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
330     if (status == napi_ok && obj != nullptr) {
331         albumCapacity = obj->smartAlbumAssetPtr->GetAlbumCapacity();
332         status = napi_create_int32(env, albumCapacity, &jsResult);
333         if (status == napi_ok) {
334             return jsResult;
335         }
336     }
337 
338     return undefinedResult;
339 }
340 
JSGetSmartAlbumCategoryId(napi_env env,napi_callback_info info)341 napi_value SmartAlbumNapi::JSGetSmartAlbumCategoryId(napi_env env, napi_callback_info info)
342 {
343     napi_status status;
344     napi_value jsResult = nullptr;
345     napi_value undefinedResult = nullptr;
346     SmartAlbumNapi* obj = nullptr;
347     int32_t categoryId;
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         categoryId = obj->smartAlbumAssetPtr->GetCategoryId();
360         status = napi_create_int32(env, categoryId, &jsResult);
361         if (status == napi_ok) {
362             return jsResult;
363         }
364     }
365 
366     return undefinedResult;
367 }
368 
JSGetSmartAlbumCategoryName(napi_env env,napi_callback_info info)369 napi_value SmartAlbumNapi::JSGetSmartAlbumCategoryName(napi_env env, napi_callback_info info)
370 {
371     napi_status status;
372     napi_value jsResult = nullptr;
373     napi_value undefinedResult = nullptr;
374     SmartAlbumNapi* obj = nullptr;
375     std::string categoryName = "";
376     napi_value thisVar = nullptr;
377 
378     napi_get_undefined(env, &undefinedResult);
379     GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
380     if (status != napi_ok || thisVar == nullptr) {
381         NAPI_ERR_LOG("Invalid arguments! status: %{public}d", status);
382         return undefinedResult;
383     }
384 
385     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
386     if (status == napi_ok && obj != nullptr) {
387         categoryName = obj->smartAlbumAssetPtr->GetCategoryName();
388         status = napi_create_string_utf8(env, categoryName.c_str(), NAPI_AUTO_LENGTH, &jsResult);
389         if (status == napi_ok) {
390             return jsResult;
391         }
392     }
393 
394     return undefinedResult;
395 }
396 
JSGetSmartAlbumCoverUri(napi_env env,napi_callback_info info)397 napi_value SmartAlbumNapi::JSGetSmartAlbumCoverUri(napi_env env, napi_callback_info info)
398 {
399     napi_status status;
400     napi_value jsResult = nullptr;
401     napi_value undefinedResult = nullptr;
402     SmartAlbumNapi* obj = nullptr;
403     std::string coverUri = "";
404     napi_value thisVar = nullptr;
405 
406     napi_get_undefined(env, &undefinedResult);
407     GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
408     if (status != napi_ok || thisVar == nullptr) {
409         NAPI_ERR_LOG("Invalid arguments! status: %{public}d", status);
410         return undefinedResult;
411     }
412 
413     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
414     if (status == napi_ok && obj != nullptr) {
415         coverUri = obj->smartAlbumAssetPtr->GetCoverUri();
416         status = napi_create_string_utf8(env, coverUri.c_str(), NAPI_AUTO_LENGTH, &jsResult);
417         if (status == napi_ok) {
418             return jsResult;
419         }
420     }
421 
422     return undefinedResult;
423 }
424 
JSGetSmartAlbumUri(napi_env env,napi_callback_info info)425 napi_value SmartAlbumNapi::JSGetSmartAlbumUri(napi_env env, napi_callback_info info)
426 {
427     napi_status status;
428     napi_value jsResult = nullptr;
429     napi_value undefinedResult = nullptr;
430     SmartAlbumNapi* obj = nullptr;
431     std::string albumUri = "";
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     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
441     if (status == napi_ok && obj != nullptr) {
442         albumUri = obj->GetSmartAlbumUri();
443         status = napi_create_string_utf8(env, albumUri.c_str(), NAPI_AUTO_LENGTH, &jsResult);
444         if (status == napi_ok) {
445             return jsResult;
446         }
447     }
448     return undefinedResult;
449 }
450 
JSGetSmartAlbumDateModified(napi_env env,napi_callback_info info)451 napi_value SmartAlbumNapi::JSGetSmartAlbumDateModified(napi_env env, napi_callback_info info)
452 {
453     napi_status status;
454     napi_value undefinedResult = nullptr;
455     napi_value thisVar = nullptr;
456 
457     napi_get_undefined(env, &undefinedResult);
458     GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
459     if ((status != napi_ok) || (thisVar == nullptr)) {
460         NAPI_ERR_LOG("Invalid arguments! status: %{public}d", status);
461         return undefinedResult;
462     }
463     SmartAlbumNapi* obj = nullptr;
464     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
465     if ((status == napi_ok) && (obj != nullptr)) {
466         int64_t dateModified = obj->smartAlbumAssetPtr->GetAlbumDateModified();
467         napi_value jsResult = nullptr;
468         status = napi_create_int64(env, dateModified, &jsResult);
469         if (status == napi_ok) {
470             return jsResult;
471         }
472     }
473     return undefinedResult;
474 }
475 
CommitModifyNative(const SmartAlbumNapiAsyncContext & albumContext)476 static void CommitModifyNative(const SmartAlbumNapiAsyncContext &albumContext)
477 {
478     SmartAlbumNapiAsyncContext *context = const_cast<SmartAlbumNapiAsyncContext *>(&albumContext);
479     CHECK_NULL_PTR_RETURN_VOID(context, "Async context is null");
480     DataShare::DataSharePredicates predicates;
481     DataShare::DataShareValuesBucket valuesBucket;
482     int32_t changedRows;
483     NAPI_DEBUG_LOG("CommitModifyNative = %{pubilc}s", context->objectPtr->GetAlbumName().c_str());
484     if (MediaFileUtils::CheckDisplayName(context->objectPtr->GetAlbumName())) {
485         valuesBucket.Put(SMARTALBUM_DB_NAME, context->objectPtr->GetAlbumName());
486         predicates.SetWhereClause(SMARTALBUM_DB_ID + " = " + std::to_string(context->objectPtr->GetAlbumId()));
487         Uri commitModifyUri(MEDIALIBRARY_DATA_URI + "/" + MEDIA_SMARTALBUMOPRN +
488                             "/" + MEDIA_SMARTALBUMOPRN_MODIFYALBUM);
489         changedRows = UserFileClient::Update(commitModifyUri, predicates, valuesBucket);
490     } else {
491         changedRows = JS_E_DISPLAYNAME;
492     }
493     context->changedRows = changedRows;
494 }
JSAddAssetExecute(SmartAlbumNapiAsyncContext * context)495 static void JSAddAssetExecute(SmartAlbumNapiAsyncContext *context)
496 {
497     CHECK_NULL_PTR_RETURN_VOID(context, "Async context is null");
498     Uri addAssetUri(MEDIALIBRARY_DATA_URI + "/" + MEDIA_SMARTALBUMMAPOPRN + "/" +
499         MEDIA_SMARTALBUMMAPOPRN_ADDSMARTALBUM);
500     for (int32_t id : context->assetIds) {
501         DataShare::DataShareValuesBucket valuesBucket;
502         valuesBucket.Put(SMARTALBUMMAP_DB_ALBUM_ID, context->objectPtr->GetAlbumId());
503         valuesBucket.Put(SMARTALBUMMAP_DB_CHILD_ASSET_ID, id);
504         context->changedRows = UserFileClient::Insert(addAssetUri, valuesBucket);
505     }
506 }
507 
JSRemoveAssetExecute(SmartAlbumNapiAsyncContext * context)508 static void JSRemoveAssetExecute(SmartAlbumNapiAsyncContext *context)
509 {
510     CHECK_NULL_PTR_RETURN_VOID(context, "Async context is null");
511     Uri removeAssetUri(MEDIALIBRARY_DATA_URI + "/" + MEDIA_SMARTALBUMMAPOPRN + "/" +
512         MEDIA_SMARTALBUMMAPOPRN_REMOVESMARTALBUM);
513     for (int32_t id : context->assetIds) {
514         DataShare::DataShareValuesBucket valuesBucket;
515         valuesBucket.Put(SMARTALBUMMAP_DB_ALBUM_ID, context->objectPtr->GetAlbumId());
516         valuesBucket.Put(SMARTALBUMMAP_DB_CHILD_ASSET_ID, id);
517         context->changedRows = UserFileClient::Insert(removeAssetUri, context->valuesBucket);
518     }
519 }
520 
JSCommitModifyCompleteCallback(napi_env env,napi_status status,SmartAlbumNapiAsyncContext * context)521 static void JSCommitModifyCompleteCallback(napi_env env, napi_status status, SmartAlbumNapiAsyncContext *context)
522 {
523     CHECK_NULL_PTR_RETURN_VOID(context, "Async context is null");
524     std::unique_ptr<JSAsyncContextOutput> jsContext = std::make_unique<JSAsyncContextOutput>();
525     jsContext->status = false;
526     if (context->changedRows != -1) {
527         napi_create_int32(env, context->changedRows, &jsContext->data);
528         napi_get_undefined(env, &jsContext->error);
529         jsContext->status = true;
530     } else {
531         napi_get_undefined(env, &jsContext->data);
532         MediaLibraryNapiUtils::CreateNapiErrorObject(env, jsContext->error, ERR_INVALID_OUTPUT,
533                                                      "Failed to obtain fetchFileResult from DB");
534     }
535 
536     if (context->work != nullptr) {
537         MediaLibraryNapiUtils::InvokeJSAsyncMethod(env, context->deferred, context->callbackRef,
538                                                    context->work, *jsContext);
539     }
540     delete context;
541 }
542 
JSAddAssetCompleteCallback(napi_env env,napi_status status,SmartAlbumNapiAsyncContext * context)543 static void JSAddAssetCompleteCallback(napi_env env, napi_status status, SmartAlbumNapiAsyncContext *context)
544 {
545     CHECK_NULL_PTR_RETURN_VOID(context, "Async context is null");
546     std::unique_ptr<JSAsyncContextOutput> jsContext = std::make_unique<JSAsyncContextOutput>();
547     jsContext->status = false;
548     if (context->changedRows != -1 && context->changedRows != 0) {
549         napi_create_int32(env, context->changedRows, &jsContext->data);
550         napi_get_undefined(env, &jsContext->error);
551         jsContext->status = true;
552     } else {
553         napi_get_undefined(env, &jsContext->data);
554         MediaLibraryNapiUtils::CreateNapiErrorObject(env, jsContext->error, ERR_INVALID_OUTPUT,
555                                                      "Failed to obtain fetchFileResult from DB");
556     }
557 
558     if (context->work != nullptr) {
559         MediaLibraryNapiUtils::InvokeJSAsyncMethod(env, context->deferred, context->callbackRef,
560                                                    context->work, *jsContext);
561     }
562     delete context;
563 }
564 
JSRemoveAssetCompleteCallback(napi_env env,napi_status status,SmartAlbumNapiAsyncContext * context)565 static void JSRemoveAssetCompleteCallback(napi_env env, napi_status status, SmartAlbumNapiAsyncContext *context)
566 {
567     CHECK_NULL_PTR_RETURN_VOID(context, "Async context is null");
568     std::unique_ptr<JSAsyncContextOutput> jsContext = std::make_unique<JSAsyncContextOutput>();
569     jsContext->status = false;
570 
571     if (context->changedRows != -1 && context->changedRows != 0) {
572         napi_create_int32(env, context->changedRows, &jsContext->data);
573         napi_get_undefined(env, &jsContext->error);
574         jsContext->status = true;
575     } else {
576         napi_get_undefined(env, &jsContext->data);
577         MediaLibraryNapiUtils::CreateNapiErrorObject(env, jsContext->error, ERR_INVALID_OUTPUT,
578                                                      "Failed to obtain fetchFileResult from DB");
579     }
580 
581     if (context->work != nullptr) {
582         MediaLibraryNapiUtils::InvokeJSAsyncMethod(env, context->deferred, context->callbackRef,
583                                                    context->work, *jsContext);
584     }
585     delete context;
586 }
587 
ConvertCommitJSArgsToNative(napi_env env,size_t argc,const napi_value argv[],SmartAlbumNapiAsyncContext & asyncContext)588 static napi_value ConvertCommitJSArgsToNative(napi_env env, size_t argc, const napi_value argv[],
589     SmartAlbumNapiAsyncContext &asyncContext)
590 {
591     const int32_t refCount = 1;
592     napi_value result;
593     auto context = &asyncContext;
594 
595     NAPI_ASSERT(env, argv != nullptr, "Argument list is empty");
596 
597     for (size_t i = PARAM0; i < argc; i++) {
598         napi_valuetype valueType = napi_undefined;
599         napi_typeof(env, argv[i], &valueType);
600         if (i == PARAM0 && valueType == napi_function) {
601             napi_create_reference(env, argv[i], refCount, &context->callbackRef);
602         } else {
603             NAPI_ASSERT(env, false, "type mismatch");
604         }
605     }
606 
607     // Return true napi_value if params are successfully obtained
608     napi_get_boolean(env, true, &result);
609     return result;
610 }
611 
GetAssetIds(napi_env env,napi_value param,SmartAlbumNapiAsyncContext & context)612 static napi_value GetAssetIds(napi_env env, napi_value param, SmartAlbumNapiAsyncContext &context)
613 {
614     uint32_t arraySize = 0;
615     if (!MediaLibraryNapiUtils::IsArrayForNapiValue(env, param, arraySize)) {
616         NAPI_ERR_LOG("GetAssetIds get args fail, not array");
617         return nullptr;
618     }
619     string uri = "";
620     for (uint32_t i = 0; i < arraySize; i++) {
621         napi_value jsValue = nullptr;
622         int32_t result;
623         if ((napi_get_element(env, param, i, &jsValue)) != napi_ok) {
624             NAPI_ERR_LOG("GetAssetIds get args fail");
625             return nullptr;
626         }
627         if (napi_get_value_int32(env, jsValue, &result) != napi_ok) {
628             NAPI_ERR_LOG("get ids value fail");
629             return nullptr;
630         } else {
631             NAPI_ERR_LOG("GetAssetIds id = %{public}d", result);
632             context.assetIds.push_back(result);
633         }
634     }
635     napi_value res;
636     napi_get_undefined(env, &res);
637     return res;
638 }
639 
GetJSArgsForAsset(napi_env env,size_t argc,const napi_value argv[],SmartAlbumNapiAsyncContext & asyncContext)640 napi_value GetJSArgsForAsset(napi_env env, size_t argc,
641                              const napi_value argv[],
642                              SmartAlbumNapiAsyncContext &asyncContext)
643 {
644     const int32_t refCount = 1;
645     napi_value result = nullptr;
646     auto context = &asyncContext;
647 
648     NAPI_ASSERT(env, argv != nullptr, "Argument list is empty");
649 
650     for (size_t i = PARAM0; i < argc; i++) {
651         napi_valuetype valueType = napi_undefined;
652         napi_typeof(env, argv[i], &valueType);
653         if (i == PARAM0) {
654             napi_value res = GetAssetIds(env, argv[PARAM0], asyncContext);
655             CHECK_NULL_PTR_RETURN_UNDEFINED(env, res, result, "Failed to obtain arguments ids");
656         } else if (i == PARAM1 && valueType == napi_function) {
657             napi_create_reference(env, argv[i], refCount, &context->callbackRef);
658             break;
659         } else {
660             NAPI_ASSERT(env, false, "type mismatch");
661         }
662     }
663     // Return true napi_value if params are successfully obtained
664     napi_get_boolean(env, true, &result);
665     return result;
666 }
667 
JSAddAsset(napi_env env,napi_callback_info info)668 napi_value SmartAlbumNapi::JSAddAsset(napi_env env, napi_callback_info info)
669 {
670     napi_status status;
671     napi_value result = nullptr;
672     size_t argc = ARGS_TWO;
673     napi_value argv[ARGS_TWO] = {0};
674     napi_value thisVar = nullptr;
675     napi_value resource = nullptr;
676     GET_JS_ARGS(env, info, argc, argv, thisVar);
677     NAPI_ASSERT(env, (argc == ARGS_ONE || argc == ARGS_TWO), "requires 2 parameter maximum");
678     napi_get_undefined(env, &result);
679     std::unique_ptr<SmartAlbumNapiAsyncContext> asyncContext = std::make_unique<SmartAlbumNapiAsyncContext>();
680 
681     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
682     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
683         result = GetJSArgsForAsset(env, argc, argv, *asyncContext);
684         CHECK_NULL_PTR_RETURN_UNDEFINED(env, result, result, "JSAddAsset fail ");
685 
686         NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result);
687         NAPI_CREATE_RESOURCE_NAME(env, resource, "JSAddAsset", asyncContext);
688 
689         asyncContext->objectPtr = asyncContext->objectInfo->smartAlbumAssetPtr;
690         CHECK_NULL_PTR_RETURN_UNDEFINED(env, asyncContext->objectPtr, result, "SmartAlbumAsset is nullptr");
691 
692         status = napi_create_async_work(
693             env, nullptr, resource, [](napi_env env, void* data) {
694                 auto context = static_cast<SmartAlbumNapiAsyncContext*>(data);
695                 JSAddAssetExecute(context);
696             },
697             reinterpret_cast<CompleteCallback>(JSAddAssetCompleteCallback),
698             static_cast<void*>(asyncContext.get()), &asyncContext->work);
699         if (status != napi_ok) {
700             napi_get_undefined(env, &result);
701         } else {
702             napi_queue_async_work(env, asyncContext->work);
703             asyncContext.release();
704         }
705     }
706 
707     return result;
708 }
709 
JSRemoveAsset(napi_env env,napi_callback_info info)710 napi_value SmartAlbumNapi::JSRemoveAsset(napi_env env, napi_callback_info info)
711 {
712     napi_status status;
713     napi_value result = nullptr;
714     size_t argc = ARGS_TWO;
715     napi_value argv[ARGS_TWO] = {0};
716     napi_value thisVar = nullptr;
717     napi_value resource = nullptr;
718     GET_JS_ARGS(env, info, argc, argv, thisVar);
719     NAPI_ASSERT(env, (argc == ARGS_ONE || argc == ARGS_TWO), "requires 2 parameter maximum");
720     napi_get_undefined(env, &result);
721     std::unique_ptr<SmartAlbumNapiAsyncContext> asyncContext = std::make_unique<SmartAlbumNapiAsyncContext>();
722 
723     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
724     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
725         result = GetJSArgsForAsset(env, argc, argv, *asyncContext);
726         CHECK_NULL_PTR_RETURN_UNDEFINED(env, result, result, "JSRemoveAsset fail ");
727 
728         NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result);
729         NAPI_CREATE_RESOURCE_NAME(env, resource, "JSRemoveAsset", asyncContext);
730 
731         asyncContext->objectPtr = asyncContext->objectInfo->smartAlbumAssetPtr;
732         CHECK_NULL_PTR_RETURN_UNDEFINED(env, asyncContext->objectPtr, result, "SmartAlbumAsset is nullptr");
733 
734         status = napi_create_async_work(
735             env, nullptr, resource, [](napi_env env, void* data) {
736                 auto context = static_cast<SmartAlbumNapiAsyncContext*>(data);
737                 JSRemoveAssetExecute(context);
738             },
739             reinterpret_cast<CompleteCallback>(JSRemoveAssetCompleteCallback),
740             static_cast<void*>(asyncContext.get()), &asyncContext->work);
741         if (status != napi_ok) {
742             napi_get_undefined(env, &result);
743         } else {
744             napi_queue_async_work(env, asyncContext->work);
745             asyncContext.release();
746         }
747     }
748 
749     return result;
750 }
751 
JSCommitModify(napi_env env,napi_callback_info info)752 napi_value SmartAlbumNapi::JSCommitModify(napi_env env, napi_callback_info info)
753 {
754     napi_status status;
755     napi_value result = nullptr;
756     size_t argc = ARGS_ONE;
757     napi_value argv[ARGS_ONE] = {0};
758     napi_value thisVar = nullptr;
759     napi_value resource = nullptr;
760     GET_JS_ARGS(env, info, argc, argv, thisVar);
761     NAPI_ASSERT(env, (argc == ARGS_ZERO || argc == ARGS_ONE), "requires 1 parameter maximum");
762     napi_get_undefined(env, &result);
763     std::unique_ptr<SmartAlbumNapiAsyncContext> asyncContext = std::make_unique<SmartAlbumNapiAsyncContext>();
764 
765     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
766     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
767         result = ConvertCommitJSArgsToNative(env, argc, argv, *asyncContext);
768         CHECK_NULL_PTR_RETURN_UNDEFINED(env, result, result, "JSCommitModify fail ");
769 
770         NAPI_CREATE_PROMISE(env, asyncContext->callbackRef, asyncContext->deferred, result);
771         NAPI_CREATE_RESOURCE_NAME(env, resource, "JSCommitModify", asyncContext);
772 
773         asyncContext->objectPtr = asyncContext->objectInfo->smartAlbumAssetPtr;
774         CHECK_NULL_PTR_RETURN_UNDEFINED(env, asyncContext->objectPtr, result, "SmartAlbumAsset is nullptr");
775 
776         status = napi_create_async_work(
777             env, nullptr, resource, [](napi_env env, void* data) {
778                 auto context = static_cast<SmartAlbumNapiAsyncContext*>(data);
779                 CommitModifyNative(*context);
780             },
781             reinterpret_cast<CompleteCallback>(JSCommitModifyCompleteCallback),
782             static_cast<void*>(asyncContext.get()), &asyncContext->work);
783         if (status != napi_ok) {
784             napi_get_undefined(env, &result);
785         } else {
786             napi_queue_async_work(env, asyncContext->work);
787             asyncContext.release();
788         }
789     }
790 
791     return result;
792 }
793 
GetFetchOptionsParam(napi_env env,napi_value arg,const SmartAlbumNapiAsyncContext & context,bool & err)794 static void GetFetchOptionsParam(napi_env env, napi_value arg, const SmartAlbumNapiAsyncContext &context, bool &err)
795 {
796     SmartAlbumNapiAsyncContext *asyncContext = const_cast<SmartAlbumNapiAsyncContext *>(&context);
797     CHECK_NULL_PTR_RETURN_VOID(asyncContext, "Async context is null");
798     char buffer[PATH_MAX];
799     size_t res;
800     uint32_t len = 0;
801     napi_value property = nullptr;
802     napi_value stringItem = nullptr;
803     bool present = false;
804     bool boolResult = false;
805 
806     napi_has_named_property(env, arg, "selections", &present);
807     if (present) {
808         if (napi_get_named_property(env, arg, "selections", &property) != napi_ok
809             || napi_get_value_string_utf8(env, property, buffer, PATH_MAX, &res) != napi_ok) {
810             NAPI_ERR_LOG("Could not get the string argument!");
811             err = true;
812             return;
813         } else {
814             asyncContext->selection = buffer;
815             CHECK_IF_EQUAL(memset_s(buffer, PATH_MAX, 0, sizeof(buffer)) == 0, "Memset for buffer failed");
816         }
817         present = false;
818     }
819 
820     napi_has_named_property(env, arg, "order", &present);
821     if (present) {
822         if (napi_get_named_property(env, arg, "order", &property) != napi_ok
823             || napi_get_value_string_utf8(env, property, buffer, PATH_MAX, &res) != napi_ok) {
824             NAPI_ERR_LOG("Could not get the string argument!");
825             err = true;
826             return;
827         } else {
828             asyncContext->order = buffer;
829             CHECK_IF_EQUAL(memset_s(buffer, PATH_MAX, 0, sizeof(buffer)) == 0, "Memset for buffer failed");
830         }
831         present = false;
832     }
833 
834     napi_has_named_property(env, arg, "selectionArgs", &present);
835     if (present && napi_get_named_property(env, arg, "selectionArgs", &property) == napi_ok &&
836         napi_is_array(env, property, &boolResult) == napi_ok && boolResult) {
837         napi_get_array_length(env, property, &len);
838         for (size_t i = 0; i < len; i++) {
839             napi_get_element(env, property, i, &stringItem);
840             napi_get_value_string_utf8(env, stringItem, buffer, PATH_MAX, &res);
841             asyncContext->selectionArgs.push_back(std::string(buffer));
842             CHECK_IF_EQUAL(memset_s(buffer, PATH_MAX, 0, sizeof(buffer)) == 0, "Memset for buffer failed");
843         }
844     } else {
845         NAPI_ERR_LOG("Could not get the string argument!");
846         err = true;
847     }
848 }
849 
ConvertJSArgsToNative(napi_env env,size_t argc,const napi_value argv[],SmartAlbumNapiAsyncContext & asyncContext)850 static napi_value ConvertJSArgsToNative(napi_env env, size_t argc, const napi_value argv[],
851     SmartAlbumNapiAsyncContext &asyncContext)
852 {
853     string str = "";
854     std::vector<string> strArr;
855     string order = "";
856     bool err = false;
857     const int32_t refCount = 1;
858     napi_value result;
859     auto context = &asyncContext;
860 
861     NAPI_ASSERT(env, argv != nullptr, "Argument list is empty");
862 
863     for (size_t i = PARAM0; i < argc; i++) {
864         napi_valuetype valueType = napi_undefined;
865         napi_typeof(env, argv[i], &valueType);
866 
867         if (i == PARAM0 && valueType == napi_object) {
868             GetFetchOptionsParam(env, argv[PARAM0], asyncContext, err);
869             if (err) {
870                 NAPI_ASSERT(env, false, "type mismatch");
871             }
872         } else if (i == PARAM0 && valueType == napi_function) {
873             napi_create_reference(env, argv[i], refCount, &context->callbackRef);
874             break;
875         } else if (i == PARAM1 && valueType == napi_function) {
876             napi_create_reference(env, argv[i], refCount, &context->callbackRef);
877             break;
878         } else {
879             NAPI_ASSERT(env, false, "type mismatch");
880         }
881     }
882 
883     // Return true napi_value if params are successfully obtained
884     napi_get_boolean(env, true, &result);
885     return result;
886 }
887 
UpdateSelection(SmartAlbumNapiAsyncContext * context)888 static void UpdateSelection(SmartAlbumNapiAsyncContext *context)
889 {
890     if (context->resultNapiType == ResultNapiType::TYPE_USERFILE_MGR) {
891         context->predicates.EqualTo(SMARTALBUMMAP_DB_ALBUM_ID, context->objectPtr->GetAlbumId());
892         if (context->objectPtr->GetAlbumId() == TRASH_ALBUM_ID_VALUES) {
893             context->predicates.NotEqualTo(MEDIA_DATA_DB_DATE_TRASHED, "0");
894         } else {
895             context->predicates.EqualTo(MEDIA_DATA_DB_DATE_TRASHED, "0");
896         }
897         MediaLibraryNapiUtils::UpdateMediaTypeSelections(context);
898     } else {
899         string trashPrefix;
900         if (context->objectPtr->GetAlbumId() == TRASH_ALBUM_ID_VALUES) {
901             trashPrefix = MEDIA_DATA_DB_DATE_TRASHED + " <> ? AND " + SMARTALBUMMAP_DB_ALBUM_ID + " = ? ";
902         } else {
903             trashPrefix = MEDIA_DATA_DB_DATE_TRASHED + " = ? AND " + SMARTALBUMMAP_DB_ALBUM_ID + " = ? ";
904         }
905         MediaLibraryNapiUtils::AppendFetchOptionSelection(context->selection, trashPrefix);
906         context->selectionArgs.emplace_back("0");
907         context->selectionArgs.emplace_back(std::to_string(context->objectPtr->GetAlbumId()));
908     }
909 }
910 
GetFileAssetsNative(napi_env env,void * data)911 static void GetFileAssetsNative(napi_env env, void *data)
912 {
913     MediaLibraryTracer tracer;
914     tracer.Start("GetFileAssetsNative");
915 
916     auto context = static_cast<SmartAlbumNapiAsyncContext *>(data);
917     CHECK_NULL_PTR_RETURN_VOID(context, "Async context is null");
918 
919     UpdateSelection(context);
920     context->predicates.SetWhereClause(context->selection);
921     context->predicates.SetWhereArgs(context->selectionArgs);
922     context->predicates.SetOrder(context->order);
923     if (context->fetchColumn.empty()) {
924         context->fetchColumn.push_back("*");
925     }
926     string queryUri = MEDIALIBRARY_DATA_ABILITY_PREFIX +
927         (MediaFileUtils::GetNetworkIdFromUri(context->objectPtr->GetAlbumUri())) +
928         MEDIALIBRARY_DATA_URI_IDENTIFIER + "/" + MEDIA_ALBUMOPRN_QUERYALBUM + "/" + ASSETMAP_VIEW_NAME;
929     MediaLibraryNapiUtils::UriAddFragmentTypeMask(queryUri, context->typeMask);
930     Uri uri(queryUri);
931     auto resultSet = UserFileClient::Query(uri, context->predicates, context->fetchColumn);
932     context->fetchResult = std::make_unique<FetchResult<FileAsset>>(move(resultSet));
933     context->fetchResult->SetNetworkId(
934         MediaFileUtils::GetNetworkIdFromUri(context->objectPtr->GetAlbumUri()));
935     if (context->resultNapiType == ResultNapiType::TYPE_USERFILE_MGR) {
936         context->fetchResult->resultNapiType_ = context->resultNapiType;
937     }
938 }
939 
JSGetFileAssetsCompleteCallback(napi_env env,napi_status status,void * data)940 static void JSGetFileAssetsCompleteCallback(napi_env env, napi_status status, void *data)
941 {
942     MediaLibraryTracer tracer;
943     tracer.Start("JSGetFileAssetsCompleteCallback");
944 
945     auto context = static_cast<SmartAlbumNapiAsyncContext *>(data);
946     CHECK_NULL_PTR_RETURN_VOID(context, "Async context is null");
947 
948     std::unique_ptr<JSAsyncContextOutput> jsContext = std::make_unique<JSAsyncContextOutput>();
949     jsContext->status = false;
950 
951     if (context->fetchResult != nullptr) {
952         if (context->fetchResult->GetCount() < 0) {
953             napi_get_undefined(env, &jsContext->data);
954             MediaLibraryNapiUtils::CreateNapiErrorObject(env, jsContext->error, ERR_MEM_ALLOCATION,
955                 "find no data by options");
956         } else {
957             napi_value fetchRes = FetchFileResultNapi::CreateFetchFileResult(env, move(context->fetchResult));
958             if (fetchRes == nullptr) {
959                 NAPI_ERR_LOG("Failed to get file asset napi object");
960                 napi_get_undefined(env, &jsContext->data);
961                 MediaLibraryNapiUtils::CreateNapiErrorObject(env, jsContext->error, ERR_MEM_ALLOCATION,
962                     "Failed to create js object for FetchFileResult");
963             } else {
964                 jsContext->data = fetchRes;
965                 napi_get_undefined(env, &jsContext->error);
966                 jsContext->status = true;
967             }
968         }
969     } else {
970         NAPI_ERR_LOG("No fetch file result found!");
971         napi_get_undefined(env, &jsContext->data);
972         MediaLibraryNapiUtils::CreateNapiErrorObject(env, jsContext->error, ERR_INVALID_OUTPUT,
973                                                      "Failed to obtain fetchFileResult from DB");
974     }
975 
976     tracer.Finish();
977     if (context->work != nullptr) {
978         MediaLibraryNapiUtils::InvokeJSAsyncMethod(env, context->deferred, context->callbackRef,
979                                                    context->work, *jsContext);
980     }
981     delete context;
982 }
983 
JSGetSmartAlbumFileAssets(napi_env env,napi_callback_info info)984 napi_value SmartAlbumNapi::JSGetSmartAlbumFileAssets(napi_env env, napi_callback_info info)
985 {
986     napi_status status;
987     napi_value result = nullptr;
988     constexpr int maxArgs = 2;
989     size_t argc = maxArgs;
990     napi_value argv[maxArgs] = {0};
991     napi_value thisVar = nullptr;
992 
993     GET_JS_ARGS(env, info, argc, argv, thisVar);
994     NAPI_ASSERT(env, ((argc == ARGS_ZERO) || (argc == ARGS_ONE) || (argc == ARGS_TWO)),
995                 "requires 2 parameter maximum");
996 
997     napi_get_undefined(env, &result);
998     std::unique_ptr<SmartAlbumNapiAsyncContext> asyncContext = std::make_unique<SmartAlbumNapiAsyncContext>();
999     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&asyncContext->objectInfo));
1000     asyncContext->resultNapiType = ResultNapiType::TYPE_MEDIALIBRARY;
1001     if (status == napi_ok && asyncContext->objectInfo != nullptr) {
1002         result = ConvertJSArgsToNative(env, argc, argv, *asyncContext);
1003         CHECK_NULL_PTR_RETURN_UNDEFINED(env, result, result, "Failed to obtain arguments");
1004 
1005         asyncContext->objectPtr = asyncContext->objectInfo->smartAlbumAssetPtr;
1006         CHECK_NULL_PTR_RETURN_UNDEFINED(env, asyncContext->objectPtr, result, "SmartAlbumAsset is nullptr");
1007 
1008         result = MediaLibraryNapiUtils::NapiCreateAsyncWork(env, asyncContext, "JSGetSmartAlbumFileAssets",
1009             GetFileAssetsNative, JSGetFileAssetsCompleteCallback);
1010     }
1011 
1012     return result;
1013 }
1014 
UserFileMgrGetAssets(napi_env env,napi_callback_info info)1015 napi_value SmartAlbumNapi::UserFileMgrGetAssets(napi_env env, napi_callback_info info)
1016 {
1017     napi_value ret = nullptr;
1018     unique_ptr<SmartAlbumNapiAsyncContext> asyncContext = make_unique<SmartAlbumNapiAsyncContext>();
1019     CHECK_NULL_PTR_RETURN_UNDEFINED(env, asyncContext, ret, "asyncContext context is null");
1020 
1021     asyncContext->mediaTypes.push_back(MEDIA_TYPE_IMAGE);
1022     asyncContext->mediaTypes.push_back(MEDIA_TYPE_VIDEO);
1023     CHECK_ARGS(env, MediaLibraryNapiUtils::ParseAssetFetchOptCallback(env, info, asyncContext), asyncContext,
1024         JS_ERR_PARAMETER_INVALID);
1025     asyncContext->resultNapiType = ResultNapiType::TYPE_USERFILE_MGR;
1026     asyncContext->typeMask = asyncContext->objectInfo->GetTypeMask();
1027 
1028     asyncContext->objectPtr = asyncContext->objectInfo->smartAlbumAssetPtr;
1029     CHECK_NULL_PTR_RETURN_UNDEFINED(env, asyncContext->objectPtr, ret, "SmartAlbumAsset is nullptr");
1030 
1031     return MediaLibraryNapiUtils::NapiCreateAsyncWork(env, asyncContext, "UserFileMgrGetAssets", GetFileAssetsNative,
1032         JSGetFileAssetsCompleteCallback);
1033 }
1034 
JSRecoverAssetExecute(napi_env env,void * data)1035 static void JSRecoverAssetExecute(napi_env env, void *data)
1036 {
1037     MediaLibraryTracer tracer;
1038     tracer.Start("JSRecoverAssetExecute");
1039 
1040     auto context = static_cast<SmartAlbumNapiAsyncContext *>(data);
1041     CHECK_NULL_PTR_RETURN_VOID(context, "Async context is null");
1042 
1043     string recoverUri = MEDIALIBRARY_DATA_URI + "/" + MEDIA_SMARTALBUMMAPOPRN + "/" +
1044         MEDIA_SMARTALBUMMAPOPRN_REMOVESMARTALBUM;
1045     MediaLibraryNapiUtils::UriAddFragmentTypeMask(recoverUri, context->typeMask);
1046     Uri recoverAssetUri(recoverUri);
1047     DataShare::DataShareValuesBucket valuesBucket;
1048     valuesBucket.Put(SMARTALBUMMAP_DB_ALBUM_ID, context->objectPtr->GetAlbumId());
1049     valuesBucket.Put(SMARTALBUMMAP_DB_CHILD_ASSET_ID, stoi(MediaLibraryNapiUtils::GetFileIdFromUri(context->uri)));
1050     int retVal = UserFileClient::Insert(recoverAssetUri, valuesBucket);
1051     context->SaveError(retVal);
1052 }
1053 
JSRecoverAssetCompleteCallback(napi_env env,napi_status status,void * data)1054 static void JSRecoverAssetCompleteCallback(napi_env env, napi_status status, void *data)
1055 {
1056     MediaLibraryTracer tracer;
1057     tracer.Start("JSRecoverAssetCompleteCallback");
1058 
1059     SmartAlbumNapiAsyncContext *context = static_cast<SmartAlbumNapiAsyncContext*>(data);
1060     CHECK_NULL_PTR_RETURN_VOID(context, "Async context is null");
1061     unique_ptr<JSAsyncContextOutput> jsContext = make_unique<JSAsyncContextOutput>();
1062     CHECK_NULL_PTR_RETURN_VOID(jsContext, "jsContext context is null");
1063     jsContext->status = false;
1064     napi_get_undefined(env, &jsContext->data);
1065     if (context->error == ERR_DEFAULT) {
1066         jsContext->status = true;
1067         Media::MediaType mediaType = MediaLibraryNapiUtils::GetMediaTypeFromUri(context->uri);
1068         string notifyUri = MediaLibraryNapiUtils::GetMediaTypeUri(mediaType);
1069         Uri modifyNotify(notifyUri);
1070         UserFileClient::NotifyChange(modifyNotify);
1071     } else {
1072         context->HandleError(env, jsContext->error);
1073     }
1074     if (context->work != nullptr) {
1075         tracer.Finish();
1076         MediaLibraryNapiUtils::InvokeJSAsyncMethod(env, context->deferred, context->callbackRef,
1077             context->work, *jsContext);
1078     }
1079 
1080     delete context;
1081 }
1082 
UserFileMgrRecoverAsset(napi_env env,napi_callback_info info)1083 napi_value SmartAlbumNapi::UserFileMgrRecoverAsset(napi_env env, napi_callback_info info)
1084 {
1085     napi_value ret = nullptr;
1086     unique_ptr<SmartAlbumNapiAsyncContext> asyncContext = make_unique<SmartAlbumNapiAsyncContext>();
1087     CHECK_NULL_PTR_RETURN_UNDEFINED(env, asyncContext, ret, "asyncContext context is null");
1088 
1089     CHECK_ARGS(env, MediaLibraryNapiUtils::ParseArgsStringCallback(env, info, asyncContext, asyncContext->uri),
1090         asyncContext, JS_ERR_PARAMETER_INVALID);
1091     asyncContext->resultNapiType = ResultNapiType::TYPE_USERFILE_MGR;
1092     asyncContext->typeMask = asyncContext->objectInfo->GetTypeMask();
1093     asyncContext->objectPtr = asyncContext->objectInfo->smartAlbumAssetPtr;
1094     CHECK_NULL_PTR_RETURN_UNDEFINED(env, asyncContext->objectPtr, ret, "SmartAlbumAsset is nullptr");
1095 
1096     return MediaLibraryNapiUtils::NapiCreateAsyncWork(env, asyncContext, "UserFileMgrGetAssets", JSRecoverAssetExecute,
1097         JSRecoverAssetCompleteCallback);
1098 }
1099 
JSDeleteAssetExecute(napi_env env,void * data)1100 static void JSDeleteAssetExecute(napi_env env, void *data)
1101 {
1102     MediaLibraryTracer tracer;
1103     tracer.Start("JSDeleteAssetExecute");
1104 
1105     auto context = static_cast<SmartAlbumNapiAsyncContext *>(data);
1106     CHECK_NULL_PTR_RETURN_VOID(context, "Async context is null");
1107 
1108     string deleteId = MediaLibraryNapiUtils::GetFileIdFromUri(context->uri);
1109     string deleteUri = MEDIALIBRARY_DATA_URI + "/" + MEDIA_FILEOPRN + "/" + MEDIA_FILEOPRN_DELETEASSET + "/" + deleteId;
1110     MediaLibraryNapiUtils::UriAddFragmentTypeMask(deleteUri, context->typeMask);
1111     Uri deleteAssetUri(deleteUri);
1112     int retVal = UserFileClient::Delete(deleteAssetUri, {});
1113     context->SaveError(retVal);
1114 }
1115 
JSDeleteAssetCompleteCallback(napi_env env,napi_status status,void * data)1116 static void JSDeleteAssetCompleteCallback(napi_env env, napi_status status, void *data)
1117 {
1118     MediaLibraryTracer tracer;
1119     tracer.Start("JSDeleteAssetCompleteCallback");
1120 
1121     SmartAlbumNapiAsyncContext *context = static_cast<SmartAlbumNapiAsyncContext*>(data);
1122     CHECK_NULL_PTR_RETURN_VOID(context, "Async context is null");
1123     unique_ptr<JSAsyncContextOutput> jsContext = make_unique<JSAsyncContextOutput>();
1124     CHECK_NULL_PTR_RETURN_VOID(jsContext, "jsContext context is null");
1125     jsContext->status = false;
1126     napi_get_undefined(env, &jsContext->data);
1127     if (context->error == ERR_DEFAULT) {
1128         jsContext->status = true;
1129         Media::MediaType mediaType = MediaLibraryNapiUtils::GetMediaTypeFromUri(context->uri);
1130         string notifyUri = MediaLibraryNapiUtils::GetMediaTypeUri(mediaType);
1131         Uri modifyNotify(notifyUri);
1132         UserFileClient::NotifyChange(modifyNotify);
1133     } else {
1134         context->HandleError(env, jsContext->error);
1135     }
1136     if (context->work != nullptr) {
1137         tracer.Finish();
1138         MediaLibraryNapiUtils::InvokeJSAsyncMethod(env, context->deferred, context->callbackRef,
1139             context->work, *jsContext);
1140     }
1141 
1142     delete context;
1143 }
1144 
UserFileMgrDeleteAsset(napi_env env,napi_callback_info info)1145 napi_value SmartAlbumNapi::UserFileMgrDeleteAsset(napi_env env, napi_callback_info info)
1146 {
1147     napi_value ret = nullptr;
1148     unique_ptr<SmartAlbumNapiAsyncContext> asyncContext = make_unique<SmartAlbumNapiAsyncContext>();
1149     CHECK_NULL_PTR_RETURN_UNDEFINED(env, asyncContext, ret, "asyncContext context is null");
1150 
1151     CHECK_ARGS(env, MediaLibraryNapiUtils::ParseArgsStringCallback(env, info, asyncContext, asyncContext->uri),
1152         asyncContext, JS_ERR_PARAMETER_INVALID);
1153     asyncContext->resultNapiType = ResultNapiType::TYPE_USERFILE_MGR;
1154     asyncContext->typeMask = asyncContext->objectInfo->GetTypeMask();
1155 
1156     return MediaLibraryNapiUtils::NapiCreateAsyncWork(env, asyncContext, "UserFileMgrGetAssets", JSDeleteAssetExecute,
1157         JSDeleteAssetCompleteCallback);
1158 }
1159 } // namespace Media
1160 } // namespace OHOS
1161