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